diff --git a/.docs/.openapi/api-data.yaml b/.docs/.openapi/api-data.yaml index bd14ba55057657c5a38d47cc29875d41e5cc1e71..24ace0b9bc592045b6cc96043dc249ae513e8580 100644 --- a/.docs/.openapi/api-data.yaml +++ b/.docs/.openapi/api-data.yaml @@ -8,10 +8,10 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 - version: 1.6.2 + version: 1.7.0 externalDocs: description: Sourcecode Documentation - url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6.2/system-services-metadata/ + url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.0/system-services-metadata/ servers: - url: http://localhost description: Development instance @@ -24,22 +24,21 @@ paths: - view-endpoint summary: Get view data description: "Gets data from a view of a database. For private databases, the\ - \ user needs at least *READ* access to the associated database. Requires role\ - \ `view-database-view-data`." + \ user needs at least *READ* access to the associated database." operationId: getData parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: page in: query required: false @@ -59,32 +58,26 @@ paths: type: string format: date-time responses: - "503": - description: Failed to establish connection with the metadata service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "404": description: Failed to find view in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "409": - description: View schema could not be mapped + "403": + description: Not allowed to retrieve view data content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Request pagination is malformed + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to retrieve view data + "400": + description: Request pagination is malformed content: application/json: schema: @@ -104,6 +97,12 @@ paths: application/json: schema: type: string + "409": + description: View schema could not be mapped + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -112,22 +111,21 @@ paths: - view-endpoint summary: Get view data description: "Gets data from a view of a database. For private databases, the\ - \ user needs at least *READ* access to the associated database. Requires role\ - \ `view-database-view-data`." + \ user needs at least *READ* access to the associated database." operationId: getData_1 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: page in: query required: false @@ -147,32 +145,26 @@ paths: type: string format: date-time responses: - "503": - description: Failed to establish connection with the metadata service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "404": description: Failed to find view in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "409": - description: View schema could not be mapped + "403": + description: Not allowed to retrieve view data content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Request pagination is malformed + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to retrieve view data + "400": + description: Request pagination is malformed content: application/json: schema: @@ -192,6 +184,12 @@ paths: application/json: schema: type: string + "409": + description: View schema could not be mapped + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -210,14 +208,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -237,20 +235,20 @@ paths: type: integer format: int64 responses: - "400": - description: Request pagination or table data select query is malformed + "404": + description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or table data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find table in metadata database + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -292,14 +290,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -312,20 +310,20 @@ paths: $ref: "#/components/schemas/TupleUpdateDto" required: true responses: - "400": - description: Request pagination or table data select query is malformed + "404": + description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or table data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find table in metadata database + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -354,14 +352,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -374,21 +372,12 @@ paths: $ref: "#/components/schemas/TupleDto" required: true responses: - "404": - description: Failed to find table in metadata database or blob in storage - service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "400": description: Request pagination or table data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "201": - description: Created table data "503": description: Failed to establish connection with the metadata service or storage service @@ -402,6 +391,15 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "201": + description: Created table data + "404": + description: Failed to find table in metadata database or blob in storage + service + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -418,14 +416,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -438,20 +436,20 @@ paths: $ref: "#/components/schemas/TupleDeleteDto" required: true responses: - "400": - description: Request pagination or table data select query is malformed + "404": + description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or table data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find table in metadata database + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -481,14 +479,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -508,20 +506,20 @@ paths: type: integer format: int64 responses: - "400": - description: Request pagination or table data select query is malformed + "404": + description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or table data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find table in metadata database + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -565,14 +563,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -592,8 +590,21 @@ paths: type: integer format: int64 responses: - "503": - description: Failed to communicate with database + "404": + description: Failed to find database in metadata database or query in query + store of the data database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Not allowed to retrieve subset data + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "400": + description: Invalid pagination content: application/json: schema: @@ -619,21 +630,8 @@ paths: application/json: schema: type: string - "400": - description: Invalid pagination - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database in metadata database or query in query - store of the data database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to retrieve subset data + "503": + description: Failed to communicate with database content: application/json: schema: @@ -655,14 +653,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -682,8 +680,21 @@ paths: type: integer format: int64 responses: - "503": - description: Failed to communicate with database + "404": + description: Failed to find database in metadata database or query in query + store of the data database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Not allowed to retrieve subset data + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "400": + description: Invalid pagination content: application/json: schema: @@ -709,21 +720,8 @@ paths: application/json: schema: type: string - "400": - description: Invalid pagination - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database in metadata database or query in query - store of the data database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to retrieve subset data + "503": + description: Failed to communicate with database content: application/json: schema: @@ -743,14 +741,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: queryId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -758,8 +756,8 @@ paths: $ref: "#/components/schemas/QueryPersistDto" required: true responses: - "503": - description: Failed to communicate with database + "403": + description: Not allowed to persist subset content: application/json: schema: @@ -770,27 +768,27 @@ paths: application/json: schema: $ref: "#/components/schemas/QueryDto" - "403": - description: Not allowed to persist subset + "404": + description: Failed to find database in metadata database or query in query + store of the data database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "417": - description: Failed to persist subset + "400": + description: Malformed select query content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database in metadata database or query in query - store of the data database + "417": + description: Failed to persist subset content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Malformed select query + "503": + description: Failed to communicate with database content: application/json: schema: @@ -813,14 +811,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -835,20 +833,14 @@ paths: responses: "202": description: Imported dataset successfully - "503": - description: Failed to establish connection with the metadata service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "404": description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Import table dataset not allowed + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -859,6 +851,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Import table dataset not allowed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -878,20 +876,22 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: persisted in: query required: false schema: type: boolean responses: - "503": - description: Failed to communicate with database + "200": + description: Found subsets content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" + type: array + items: + $ref: "#/components/schemas/QueryDto" "404": description: Failed to find database in metadata database or query in query store of the data database @@ -899,16 +899,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "200": - description: Found subsets + "403": + description: Not allowed to find subsets content: application/json: schema: - type: array - items: - $ref: "#/components/schemas/QueryDto" - "403": - description: Not allowed to find subsets + $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to communicate with database content: application/json: schema: @@ -930,8 +928,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -954,7 +952,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/ExecuteStatementDto" + $ref: "#/components/schemas/SubsetDto" required: true responses: "201": @@ -963,12 +961,6 @@ paths: application/json: schema: type: string - "503": - description: Failed to communicate with database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "501": description: Failed to execute query as it contains non-supported keywords content: @@ -988,14 +980,20 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "417": + description: Failed to insert query into query store of data database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "400": description: Malformed select query content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "417": - description: Failed to insert query into query store of data database + "503": + description: Failed to communicate with database content: application/json: schema: @@ -1017,14 +1015,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -1032,20 +1030,26 @@ paths: type: string format: date-time responses: - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or view data select query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Export view data not allowed + "404": + description: Failed to find view in metadata database or export dataset content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find view in metadata database or export dataset + "503": + description: Failed to establish connection with the metadata service + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Export view data not allowed content: application/json: schema: @@ -1057,12 +1061,6 @@ paths: schema: type: string format: binary - "400": - description: Request pagination or view data select query is malformed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -1080,14 +1078,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: size in: query required: false @@ -1095,6 +1093,14 @@ paths: type: integer format: int64 responses: + "200": + description: Found table history + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/TableHistoryDto" "403": description: Find table history not allowed content: @@ -1107,26 +1113,18 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find table history in data database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "400": description: "Invalid pagination size request, must be > 0" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "200": - description: Found table history + "404": + description: Failed to find table history in data database content: application/json: schema: - type: array - items: - $ref: "#/components/schemas/TableHistoryDto" + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -1144,14 +1142,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -1159,14 +1157,14 @@ paths: type: string format: date-time responses: - "400": - description: Request pagination or table data select query is malformed + "404": + description: Failed to find table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to establish connection with the metadata service + "400": + description: Request pagination or table data select query is malformed content: application/json: schema: @@ -1178,8 +1176,8 @@ paths: schema: type: string format: binary - "404": - description: Failed to find table in metadata database + "503": + description: Failed to establish connection with the metadata service content: application/json: schema: @@ -1209,14 +1207,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true @@ -1229,31 +1227,25 @@ paths: type: string format: date-time responses: - "503": - description: Failed to communicate with database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to find subset + "200": + description: Found subset content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" + $ref: "#/components/schemas/QueryDto" + text/csv: {} "406": description: Failed to find acceptable representation content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "200": - description: Found subset + "403": + description: Not allowed to find subset content: application/json: schema: - $ref: "#/components/schemas/QueryDto" - text/csv: {} + $ref: "#/components/schemas/ApiErrorDto" "404": description: Failed to find database in metadata database or query in query store of the data database @@ -1267,6 +1259,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to communicate with database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - basicAuth: [] - bearerAuth: [] @@ -1395,9 +1393,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 11 + type: string + format: uuid + example: e41f94a6-2b94-4a12-ac0e-678684e1c070 affiliation: type: string example: Brown University @@ -1435,6 +1433,7 @@ components: required: - creators - database_id + - descriptions - id - owned_by - publication_year @@ -1445,9 +1444,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: b97cd56b-66ca-4354-9e6c-f47210cfaaec type: type: string example: database @@ -1464,6 +1463,10 @@ components: type: array items: $ref: "#/components/schemas/IdentifierTitleDto" + descriptions: + type: array + items: + $ref: "#/components/schemas/IdentifierDescriptionDto" doi: type: string example: 10.1038/nphys1170 @@ -1477,21 +1480,18 @@ components: - draft - published database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc query_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid view_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid publication_year: type: integer format: int32 @@ -1500,15 +1500,225 @@ components: type: string format: uuid example: 2f45ef7a-7f9b-4667-9156-152c87fe1ca5 + IdentifierDescriptionDto: + required: + - id + type: object + properties: + id: + type: string + format: uuid + example: e0e9692c-910b-4b60-b53a-fc7c358a917d + description: + type: string + example: "Air quality reports at Stephansplatz, Vienna" + language: + type: string + example: en + enum: + - ab + - aa + - af + - ak + - sq + - am + - ar + - an + - hy + - as + - av + - ae + - ay + - az + - bm + - ba + - eu + - be + - bn + - bh + - bi + - bs + - br + - bg + - my + - ca + - km + - ch + - ce + - ny + - zh + - cu + - cv + - kw + - co + - cr + - hr + - cs + - da + - dv + - nl + - dz + - en + - eo + - et + - ee + - fo + - fj + - fi + - fr + - ff + - gd + - gl + - lg + - ka + - de + - ki + - el + - kl + - gn + - gu + - ht + - ha + - he + - hz + - hi + - ho + - hu + - is + - io + - ig + - id + - ia + - ie + - iu + - ik + - ga + - it + - ja + - jv + - kn + - kr + - ks + - kk + - rw + - kv + - kg + - ko + - kj + - ku + - ky + - lo + - la + - lv + - lb + - li + - ln + - lt + - lu + - mk + - mg + - ms + - ml + - mt + - gv + - mi + - mr + - mh + - ro + - mn + - na + - nv + - nd + - ng + - ne + - se + - "no" + - nb + - nn + - ii + - oc + - oj + - or + - om + - os + - pi + - pa + - ps + - fa + - pl + - pt + - qu + - rm + - rn + - ru + - sm + - sg + - sa + - sc + - sr + - sn + - sd + - si + - sk + - sl + - so + - st + - nr + - es + - su + - sw + - ss + - sv + - tl + - ty + - tg + - ta + - tt + - te + - th + - bo + - ti + - to + - ts + - tn + - tr + - tk + - tw + - ug + - uk + - ur + - uz + - ve + - vi + - vo + - wa + - cy + - fy + - wo + - xh + - yi + - yo + - za + - zu + type: + type: string + example: Abstract + enum: + - Abstract + - Methods + - SeriesInformation + - TableOfContents + - TechnicalInfo + - Other IdentifierTitleDto: required: - id type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 70ce5164-fd74-413f-8712-f996b91defbf title: type: string example: Airquality Demonstrator @@ -1721,9 +1931,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 83ea2326-f8f6-4263-baf8-cdf88a54efc7 owner: $ref: "#/components/schemas/UserBriefDto" execution: @@ -1744,9 +1954,9 @@ components: items: $ref: "#/components/schemas/IdentifierBriefDto" database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc query_normalized: type: string example: SELECT `id` FROM `air_quality` @@ -1829,14 +2039,72 @@ components: line_termination: type: string example: \r\n - ExecuteStatementDto: + FilterDto: + required: + - column_id + - operator_id + - type + - value + type: object + properties: + type: + type: string + example: where + enum: + - where + - or + - and + value: + type: string + example: "1" + column_id: + type: string + format: uuid + example: 14128033-54b5-4818-a489-21b0dded86e2 + operator_id: + type: string + format: uuid + example: 67c5b54d-2eb0-4f42-8dc1-a504562e9f32 + OrderDto: required: - - statement + - column_id type: object properties: - statement: + direction: type: string - example: SELECT `id` FROM `air_quality` + example: asc + enum: + - asc + - desc + column_id: + type: string + format: uuid + example: e891ba86-0258-41a6-a8d9-ff58bc10b618 + SubsetDto: + required: + - columns + - table_id + type: object + properties: + columns: + type: array + example: + - e891ba86-0258-41a6-a8d9-ff58bc10b618 + items: + type: string + format: uuid + filter: + type: array + items: + $ref: "#/components/schemas/FilterDto" + order: + type: array + items: + $ref: "#/components/schemas/OrderDto" + table_id: + type: string + format: uuid + example: f7df2a7d-4ade-4c78-97b0-7c744d0893c7 TableHistoryDto: required: - event @@ -1850,6 +2118,10 @@ components: example: 2021-03-12T15:26:21Z event: type: string + example: INSERT + enum: + - insert + - delete total: type: integer format: int64 diff --git a/.docs/.openapi/api-metadata.yaml b/.docs/.openapi/api-metadata.yaml index 18fb71db29de89369c93de29296e1d85abc58b37..7331cf78f7d208d70973ddc04019a39bc5af993c 100644 --- a/.docs/.openapi/api-metadata.yaml +++ b/.docs/.openapi/api-metadata.yaml @@ -8,16 +8,146 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 - version: 1.6.2 + version: 1.7.0 externalDocs: description: Sourcecode Documentation - url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.6.2/system-services-metadata/ + url: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.7.0/system-services-metadata/ servers: - url: http://localhost description: Development instance - url: https://test.dbrepo.tuwien.ac.at description: Staging instance paths: + /api/user/{userId}: + get: + tags: + - user-endpoint + summary: Get user + description: Gets own user information from the metadata database. Requires + authentication. Foreign user information can only be obtained if additional + role `find-foreign-user` is present. Finding information about internal users + results in a 404 error. + operationId: find + parameters: + - name: userId + in: path + required: true + schema: + type: string + format: uuid + responses: + "403": + description: Find user is not permitted + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "200": + description: Found user + content: + application/json: + schema: + $ref: "#/components/schemas/UserDto" + "404": + description: User was not found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + security: + - bearerAuth: [] + - basicAuth: [] + put: + tags: + - user-endpoint + summary: Update user + description: Updates user with id. Requires role `modify-user-information`. + operationId: modify + parameters: + - name: userId + in: path + required: true + schema: + type: string + format: uuid + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UserUpdateDto" + required: true + responses: + "400": + description: Modify user query is malformed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Not allowed to modify user metadata + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "404": + description: Failed to find database/user in metadata database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to modify user at auth service + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "202": + description: Modified user information + content: + application/json: + schema: + $ref: "#/components/schemas/UserDto" + security: + - bearerAuth: [] + - basicAuth: [] + head: + tags: + - user-endpoint + summary: Get user + description: Gets own user information from the metadata database. Requires + authentication. Foreign user information can only be obtained if additional + role `find-foreign-user` is present. Finding information about internal users + results in a 404 error. + operationId: find_1 + parameters: + - name: userId + in: path + required: true + schema: + type: string + format: uuid + responses: + "403": + description: Find user is not permitted + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "200": + description: Found user + content: + application/json: + schema: + $ref: "#/components/schemas/UserDto" + "404": + description: User was not found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + security: + - bearerAuth: [] + - basicAuth: [] /api/database: get: tags: @@ -56,7 +186,7 @@ paths: - database-endpoint summary: Create database description: Creates a database in the container with id. Requires roles `create-database`. - operationId: create_5 + operationId: create_4 requestBody: content: application/json: @@ -64,9 +194,8 @@ paths: $ref: "#/components/schemas/CreateDatabaseDto" required: true responses: - "403": - description: Database create permission is missing or grant permissions - at broker service failed + "400": + description: Database create query is malformed or image is not supported content: application/json: schema: @@ -77,26 +206,21 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Database create query is malformed or image is not supported - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "403": + description: Database create permission is missing or grant permissions + at broker service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to fin container/user/database in metadata database + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "409": + description: Query store could not be created content: application/json: schema: @@ -107,8 +231,14 @@ paths: application/json: schema: $ref: "#/components/schemas/DatabaseBriefDto" - "409": - description: Query store could not be created + "404": + description: Failed to fin container/user/database in metadata database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to save in search service content: application/json: schema: @@ -158,14 +288,14 @@ paths: \ with HTTP method **HEAD** only the status. When the user has at least *READ*\ \ access, the status 200 is returned, 403 otherwise. Requires role `check-database-access`\ \ or `check-foreign-database-access`." - operationId: find + operationId: find_2 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -173,12 +303,6 @@ paths: type: string format: uuid responses: - "200": - description: Found database access - content: - application/json: - schema: - $ref: "#/components/schemas/DatabaseAccessDto" "403": description: No access to this database content: @@ -191,6 +315,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "200": + description: Found database access + content: + application/json: + schema: + $ref: "#/components/schemas/DatabaseAccessDto" security: - bearerAuth: [] - basicAuth: [] @@ -206,8 +336,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -221,36 +351,36 @@ paths: $ref: "#/components/schemas/CreateAccessDto" required: true responses: - "403": - description: Modify access not permitted when no access is granted in the - first place + "404": + description: Database or user not found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Access could not be updated due to connection error in the - data service + "403": + description: Modify access not permitted when no access is granted in the + first place content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Access could not be updated in the data service + "400": + description: Modify access query or database connection is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" "202": description: Modified access - "404": - description: Database or user not found + "503": + description: Access could not be updated in the data service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Modify access query or database connection is malformed + "502": + description: Access could not be updated due to connection error in the + data service content: application/json: schema: @@ -264,14 +394,14 @@ paths: summary: Give access description: Give a user with given id access to some database with given id. Requires role `create-database-access`. - operationId: create_8 + operationId: create_7 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -285,8 +415,8 @@ paths: $ref: "#/components/schemas/CreateAccessDto" required: true responses: - "502": - description: Access could not be created due to connection error + "404": + description: Database or user not found content: application/json: schema: @@ -297,30 +427,30 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Granting access query or database connection is malformed + "502": + description: Access could not be created due to connection error content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Failed giving access + "202": + description: Granting access succeeded content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Database or user not found + $ref: "#/components/schemas/DatabaseAccessDto" + "400": + description: Granting access query or database connection is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Granting access succeeded + "403": + description: Failed giving access content: application/json: schema: - $ref: "#/components/schemas/DatabaseAccessDto" + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -336,8 +466,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -345,20 +475,24 @@ paths: type: string format: uuid responses: + "403": + description: Revoke of access not permitted as no access was found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "502": description: Access could not be created due to connection error content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Revoke of access not permitted as no access was found + "503": + description: Access could not be revoked in the data service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Deleted access "400": description: Modify access query or database connection is malformed content: @@ -371,12 +505,8 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Access could not be revoked in the data service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" + "202": + description: Deleted access security: - bearerAuth: [] - basicAuth: [] @@ -389,14 +519,14 @@ paths: \ with HTTP method **HEAD** only the status. When the user has at least *READ*\ \ access, the status 200 is returned, 403 otherwise. Requires role `check-database-access`\ \ or `check-foreign-database-access`." - operationId: find_1 + operationId: find_3 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -404,12 +534,6 @@ paths: type: string format: uuid responses: - "200": - description: Found database access - content: - application/json: - schema: - $ref: "#/components/schemas/DatabaseAccessDto" "403": description: No access to this database content: @@ -422,259 +546,29 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - security: - - bearerAuth: [] - - basicAuth: [] - /api/user/{userId}: - get: - tags: - - user-endpoint - summary: Get user - description: Gets own user information from the metadata database. Requires - authentication. Foreign user information can only be obtained if additional - role `find-foreign-user` is present. Finding information about internal users - results in a 404 error. - operationId: find_2 - parameters: - - name: userId - in: path - required: true - schema: - type: string - format: uuid - responses: - "404": - description: User was not found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": - description: Found user - content: - application/json: - schema: - $ref: "#/components/schemas/UserDto" - "403": - description: Find user is not permitted - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - security: - - bearerAuth: [] - - basicAuth: [] - put: - tags: - - user-endpoint - summary: Update user - description: Updates user with id. Requires role `modify-user-information`. - operationId: modify - parameters: - - name: userId - in: path - required: true - schema: - type: string - format: uuid - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/UserUpdateDto" - required: true - responses: - "202": - description: Modified user information - content: - application/json: - schema: - $ref: "#/components/schemas/UserDto" - "403": - description: Not allowed to modify user metadata - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Modify user query is malformed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database/user in metadata database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - security: - - bearerAuth: [] - - basicAuth: [] - /api/user/{userId}/password: - put: - tags: - - user-endpoint - summary: Update user password - description: Updates password of user with id. Requires authentication. - operationId: password - parameters: - - name: userId - in: path - required: true - schema: - type: string - format: uuid - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/UserPasswordDto" - required: true - responses: - "400": - description: Invalid password payload - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Modified user password - "403": - description: Not allowed to change foreign user password - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database/user in metadata database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to get user in auth service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to auth service failed + description: Found database access content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" + $ref: "#/components/schemas/DatabaseAccessDto" security: - bearerAuth: [] - basicAuth: [] - /api/user/token: - put: - tags: - - user-endpoint - summary: Refresh token - description: Refreshes user token by refresh token. - operationId: refreshToken - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/RefreshTokenRequestDto" - required: true - responses: - "403": - description: Not allowed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Invalid refresh token - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Refreshed user token - content: - application/json: - schema: - $ref: "#/components/schemas/TokenDto" - "502": - description: Connection to auth service failed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - post: - tags: - - user-endpoint - summary: Create token - description: Creates a user token via the Auth Service. - operationId: getToken - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/LoginRequestDto" - required: true - responses: - "404": - description: Failed to find user in auth database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "428": - description: Account is not fully setup in auth service (requires password - change?) - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Invalid login request - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Obtained user token - content: - application/json: - schema: - $ref: "#/components/schemas/TokenDto" - "403": - description: Not allowed to get token - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to get user in auth service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to auth service failed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" /api/ontology/{ontologyId}: get: tags: - ontology-endpoint summary: Find ontology description: Finds an ontology with id in the metadata database. - operationId: find_3 + operationId: find_4 parameters: - name: ontologyId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: "200": description: Find one ontology @@ -699,8 +593,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -734,19 +628,19 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "202": + description: Deleted ontology successfully + content: + application/json: {} "404": description: Could not find ontology content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Deleted ontology successfully - content: - application/json: {} security: - bearerAuth: [] - basicAuth: [] @@ -762,8 +656,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -797,8 +691,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: "404": description: Could not find message @@ -825,21 +719,21 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "200": - description: Found image - content: - application/json: - schema: - $ref: "#/components/schemas/ImageDto" "404": description: Image could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "200": + description: Found image + content: + application/json: + schema: + $ref: "#/components/schemas/ImageDto" put: tags: - image-endpoint @@ -852,8 +746,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -888,17 +782,17 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "202": + description: Deleted image successfully "404": description: Image could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Deleted image successfully security: - bearerAuth: [] - basicAuth: [] @@ -909,22 +803,22 @@ paths: summary: Find identifier description: Finds an identifier with id. The response format depends on the HTTP `Accept` header set on the request. - operationId: find_6 + operationId: find_7 parameters: - name: identifierId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true schema: type: string responses: - "410": - description: Failed to retrieve from S3 endpoint + "404": + description: Identifier could not be found content: application/json: schema: @@ -935,12 +829,30 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "410": + description: Failed to retrieve from S3 endpoint + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "503": description: Failed to find in data service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Not allowed to view identifier + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "406": + description: Failed to find acceptable representation + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "200": description: Found identifier successfully content: @@ -956,27 +868,15 @@ paths: text/bibliography; style=apa: {} text/bibliography; style=ieee: {} text/bibliography; style=bibtex: {} - "400": - description: "Identifier could not be exported, the requested style is not\ - \ known" - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "409": description: Exported resource was not found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Identifier could not be found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "406": - description: Failed to find acceptable representation + "400": + description: "Identifier could not be exported, the requested style is not\ + \ known" content: application/json: schema: @@ -995,8 +895,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1004,14 +904,20 @@ paths: $ref: "#/components/schemas/IdentifierSaveDto" required: true responses: + "202": + description: Saved identifier + content: + application/json: + schema: + $ref: "#/components/schemas/IdentifierDto" "400": description: Identifier form contains invalid request data content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: "Failed to find database, table or view" + "502": + description: Connection to search service failed content: application/json: schema: @@ -1022,24 +928,18 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "404": + description: "Failed to find database, table or view" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "503": + description: Failed to save in search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Saved identifier - content: - application/json: - schema: - $ref: "#/components/schemas/IdentifierDto" security: - bearerAuth: [] - basicAuth: [] @@ -1054,8 +954,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: "403": description: Deleting identifier not permitted @@ -1063,26 +963,26 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Identifier or database could not be found + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to delete in search service + "404": + description: Identifier or database could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "202": + description: Deleted identifier + "503": + description: Failed to delete in search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Deleted identifier security: - bearerAuth: [] - basicAuth: [] @@ -1099,17 +999,23 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "202": + description: Published identifier + content: + application/json: + schema: + $ref: "#/components/schemas/IdentifierDto" "400": description: Identifier form contains invalid request data content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: "Failed to find database, table or view" + "502": + description: Connection to search service failed content: application/json: schema: @@ -1120,24 +1026,18 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "404": + description: "Failed to find database, table or view" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "503": + description: Failed to save in search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Published identifier - content: - application/json: - schema: - $ref: "#/components/schemas/IdentifierDto" security: - bearerAuth: [] - basicAuth: [] @@ -1154,8 +1054,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1163,38 +1063,38 @@ paths: $ref: "#/components/schemas/DatabaseModifyVisibilityDto" required: true responses: - "400": - description: The visibility payload is malformed + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Visibility modified successfully + "404": + description: Failed to find database in metadata database content: application/json: schema: - $ref: "#/components/schemas/DatabaseBriefDto" - "503": - description: Failed to save in search service + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Visibility modification is not permitted content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "202": + description: Visibility modified successfully content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database in metadata database + $ref: "#/components/schemas/DatabaseBriefDto" + "400": + description: The visibility payload is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Visibility modification is not permitted + "503": + description: Failed to save in search service content: application/json: schema: @@ -1208,60 +1108,35 @@ paths: - view-endpoint summary: Get view description: Gets a view with id in the metadata database. - operationId: find_7 + operationId: find_8 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "403": - description: Find view is not permitted + "404": + description: "Database, view or user could not be found" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: "Database, view or user could not be found" + "403": + description: Find view is not permitted content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" "200": description: Find view successfully - headers: - X-Username: - description: The authentication username - style: simple - Access-Control-Expose-Headers: - description: Expose custom headers - style: simple - X-Type: - description: The JDBC connection type - style: simple - X-View: - description: The view internal name - style: simple - X-Database: - description: The database internal name - style: simple - X-Password: - description: The authentication password - style: simple - X-Host: - description: The database hostname - style: simple - X-Port: - description: The database port number - style: simple content: application/json: schema: @@ -1281,14 +1156,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1296,20 +1171,20 @@ paths: $ref: "#/components/schemas/ViewUpdateDto" required: true responses: - "403": - description: Update not allowed + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "404": + description: Database or View could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Database or View could not be found + "400": + description: Update view query is malformed content: application/json: schema: @@ -1320,14 +1195,14 @@ paths: '*/*': schema: $ref: "#/components/schemas/ViewBriefDto" - "502": - description: Connection to search service failed + "403": + description: Update not allowed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Update view query is malformed + "503": + description: Failed to save in search service content: application/json: schema: @@ -1346,31 +1221,31 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "202": - description: Delete view successfully - "423": - description: Delete view resulted in an invalid query statement - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "404": description: "Database, view or user could not be found" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Delete view query is malformed + "502": + description: Connection to search service failed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "202": + description: Delete view successfully + "403": + description: Deletion not allowed content: application/json: schema: @@ -1381,14 +1256,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "400": + description: Delete view query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Deletion not allowed + "423": + description: Delete view resulted in an invalid query statement content: application/json: schema: @@ -1411,17 +1286,17 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "502": - description: Failed to establish connection with broker service + "403": + description: Access to the database is forbidden content: application/json: schema: @@ -1432,34 +1307,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to obtain queue information from broker service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": description: Find table successfully - headers: - X-Username: - description: The authentication username - style: simple - Access-Control-Expose-Headers: - description: Expose custom headers - style: simple - X-Password: - description: The authentication password - style: simple content: application/json: schema: $ref: "#/components/schemas/TableDto" - "403": - description: Access to the database is forbidden - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -1474,14 +1327,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1489,38 +1342,38 @@ paths: $ref: "#/components/schemas/TableUpdateDto" required: true responses: - "400": - description: Update table visibility payload is malformed + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "404": + description: Table could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "403": + description: Update table visibility not permitted content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Updated the table + "400": + description: Update table visibility payload is malformed content: application/json: schema: - $ref: "#/components/schemas/TableBriefDto" - "403": - description: Update table visibility not permitted + $ref: "#/components/schemas/ApiErrorDto" + "202": + description: Updated the table content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Table could not be found + $ref: "#/components/schemas/TableBriefDto" + "503": + description: Failed to save in search service content: application/json: schema: @@ -1541,43 +1394,43 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "400": - description: Delete table query resulted in an invalid query statement + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Delete table successfully - "404": - description: "Table, database or container could not be found" + "400": + description: Delete table query resulted in an invalid query statement content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "403": + description: Access to the database is forbidden content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "404": + description: "Table, database or container could not be found" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Access to the database is forbidden + "202": + description: Delete table successfully + "503": + description: Failed to save in search service content: application/json: schema: @@ -1599,29 +1452,23 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "400": - description: Failed to map column statistic to known columns - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not the owner + "400": + description: Failed to map column statistic to known columns content: application/json: schema: @@ -1632,14 +1479,20 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "403": + description: Not the owner content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" "202": description: Updated table statistics successfully + "503": + description: Failed to save in search service + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -1658,20 +1511,20 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: columnId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1679,39 +1532,39 @@ paths: $ref: "#/components/schemas/ColumnSemanticsUpdateDto" required: true responses: - "503": - description: Failed to save in search service + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Updated column semantics successfully + "403": + description: Access to the database is forbidden content: application/json: schema: - $ref: "#/components/schemas/ColumnDto" - "404": - description: Failed to find user/table/database/ontology in metadata database + $ref: "#/components/schemas/ApiErrorDto" + "400": + description: Update semantic concept query is malformed or update unit of + measurement query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "404": + description: Failed to find user/table/database/ontology in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Update semantic concept query is malformed or update unit of - measurement query is malformed + "202": + description: Updated column semantics successfully content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Access to the database is forbidden + $ref: "#/components/schemas/ColumnDto" + "503": + description: Failed to save in search service content: application/json: schema: @@ -1732,8 +1585,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1741,38 +1594,38 @@ paths: $ref: "#/components/schemas/DatabaseTransferDto" required: true responses: - "400": - description: Owner payload is malformed + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Transfer of ownership was successful + "400": + description: Owner payload is malformed content: application/json: schema: - $ref: "#/components/schemas/DatabaseBriefDto" - "503": - description: Failed to save in search service + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Transfer of ownership is not permitted content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "404": + description: Database or user could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Transfer of ownership is not permitted + "202": + description: Transfer of ownership was successful content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Database or user could not be found + $ref: "#/components/schemas/DatabaseBriefDto" + "503": + description: Failed to save in search service content: application/json: schema: @@ -1794,9 +1647,15 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "502": + description: Connection to search service failed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "200": description: Refreshed database views metadata content: @@ -1809,20 +1668,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "404": + description: Failed to find database in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database in metadata database + "503": + description: Failed to save in search service content: application/json: schema: @@ -1844,27 +1697,21 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "502": + description: Connection to search service failed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "400": description: Failed to parse payload at search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": description: Refreshed database tables metadata content: @@ -1878,7 +1725,13 @@ paths: schema: $ref: "#/components/schemas/ApiErrorDto" "404": - description: Failed to fin user/database in metadata database + description: Failed to find database in metadata database + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to save in search service content: application/json: schema: @@ -1898,9 +1751,15 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "404": + description: Database or user could not be found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "200": description: View of image was successful content: @@ -1910,12 +1769,6 @@ paths: items: type: string format: byte - "404": - description: Database or user could not be found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -1931,8 +1784,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -1940,129 +1793,45 @@ paths: $ref: "#/components/schemas/DatabaseModifyImageDto" required: true responses: - "403": - description: Modify of image is not permitted - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Database could not be found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "502": description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Modify of image was successful + "403": + description: Modify of image is not permitted content: application/json: schema: - $ref: "#/components/schemas/DatabaseBriefDto" + $ref: "#/components/schemas/ApiErrorDto" "410": description: File was not found in the Storage Service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - security: - - bearerAuth: [] - - basicAuth: [] - /api/user: - get: - tags: - - user-endpoint - summary: List users - description: "Lists users known to the metadata database. Internal users are\ - \ omitted from the result list. If the optional query parameter `username`\ - \ is present, the result list can be filtered by matching this exact username." - operationId: findAll - parameters: - - name: username - in: query - required: false - schema: - type: string - responses: - "200": - description: List users - content: - application/json: - schema: - type: array - items: - $ref: "#/components/schemas/UserBriefDto" - post: - tags: - - user-endpoint - summary: Create user - description: Creates a user in the auth service and metadata database. Requires - that no credentials are sent in the request. - operationId: create - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/CreateUserDto" - required: true - responses: - "201": - description: Created user + "202": + description: Modify of image was successful content: application/json: schema: - $ref: "#/components/schemas/UserDto" + $ref: "#/components/schemas/DatabaseBriefDto" "404": - description: Default role not found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Failed to create in auth service - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Internal authentication to the auth service is invalid - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "409": - description: User with username already exists - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Parameters are not well-formed (likely email) - content: - application/json: {} - "417": - description: User with e-mail already exists + description: Database could not be found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" "503": - description: Failed to create in auth service + description: Failed to save in search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + security: + - bearerAuth: [] + - basicAuth: [] /api/ontology: get: tags: @@ -2084,7 +1853,7 @@ paths: - ontology-endpoint summary: Create ontology description: Creates an ontology in the metadata database. Requires role `create-ontology`. - operationId: create_1 + operationId: create requestBody: content: application/json: @@ -2132,7 +1901,7 @@ paths: - message-endpoint summary: Create message description: Creates a message in the metadata database. Requires role `create-maintenance-message`. - operationId: create_2 + operationId: create_1 requestBody: content: application/json: @@ -2171,7 +1940,7 @@ paths: summary: Create image description: Creates a container image in the metadata database. Requires role `create-image`. - operationId: create_3 + operationId: create_2 requestBody: content: application/json: @@ -2179,18 +1948,18 @@ paths: $ref: "#/components/schemas/ImageCreateDto" required: true responses: - "201": - description: Created image - content: - application/json: - schema: - $ref: "#/components/schemas/ImageDto" "409": description: Image already exists content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "201": + description: Created image + content: + application/json: + schema: + $ref: "#/components/schemas/ImageDto" "400": description: Image specification is invalid content: @@ -2208,30 +1977,48 @@ paths: description: Lists all identifiers known to the metadata database operationId: findAll_4 parameters: + - name: type + in: query + required: false + schema: + type: string + enum: + - database + - subset + - table + - view + - name: status + in: query + required: false + schema: + type: string + enum: + - draft + - published - name: dbid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: qid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: vid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: tid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true @@ -2251,13 +2038,6 @@ paths: type: array items: $ref: "#/components/schemas/LdDatasetDto" - "406": - description: "Identifier could not be exported, the requested style is not\ - \ known" - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" post: tags: - identifier-endpoint @@ -2266,7 +2046,7 @@ paths: can only be created for objects the user has at least *READ* access in the associated database (requires role `create-identifier`) or for any object in any database (requires role `create-foreign-identifier`). - operationId: create_4 + operationId: create_3 requestBody: content: application/json: @@ -2274,20 +2054,14 @@ paths: $ref: "#/components/schemas/CreateIdentifierDto" required: true responses: - "201": - description: Drafted identifier - content: - application/json: - schema: - $ref: "#/components/schemas/IdentifierDto" "400": description: Identifier form contains invalid request data content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: "Failed to find database, table or view" + "502": + description: Connection to search service failed content: application/json: schema: @@ -2298,14 +2072,20 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "201": + description: Drafted identifier + content: + application/json: + schema: + $ref: "#/components/schemas/IdentifierDto" + "404": + description: "Failed to find database, table or view" content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "503": + description: Failed to save in search service content: application/json: schema: @@ -2325,9 +2105,15 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: + "404": + description: Database or user could not be found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" "200": description: Find views successfully content: @@ -2336,12 +2122,6 @@ paths: type: array items: $ref: "#/components/schemas/ViewBriefDto" - "404": - description: Database or user could not be found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -2351,14 +2131,14 @@ paths: summary: Create view description: Creates a view. This can only be performed by the database owner. Requires role `create-database-view`. - operationId: create_6 + operationId: create_5 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2366,32 +2146,26 @@ paths: $ref: "#/components/schemas/CreateViewDto" required: true responses: - "201": - description: Create view successfully - content: - application/json: - schema: - $ref: "#/components/schemas/ViewBriefDto" - "423": - description: Create view resulted in an invalid query statement + "400": + description: Create view query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "502": + description: Connection to search service failed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "201": + description: Create view successfully content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Create view query is malformed + $ref: "#/components/schemas/ViewBriefDto" + "404": + description: Failed to find database/user in metadata database. content: application/json: schema: @@ -2402,8 +2176,20 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database/user in metadata database. + "423": + description: Create view resulted in an invalid query statement + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "503": + description: Failed to save in search service + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "409": + description: View exists with name content: application/json: schema: @@ -2425,8 +2211,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: "403": description: List tables not permitted @@ -2434,12 +2220,6 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Database could not be found - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": description: List tables content: @@ -2448,6 +2228,12 @@ paths: type: array items: $ref: "#/components/schemas/TableBriefDto" + "404": + description: Database could not be found + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -2456,14 +2242,14 @@ paths: - table-endpoint summary: Create table description: Creates a table in the database with id. Requires role `create-table`. - operationId: create_7 + operationId: create_6 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2471,26 +2257,20 @@ paths: $ref: "#/components/schemas/CreateTableDto" required: true responses: - "409": - description: Create table conflicts with existing table name - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "400": description: Create table query is malformed content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: "Database, container or user could not be found" + "409": + description: Create table conflicts with existing table name content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "503": - description: Failed to save in search service + "502": + description: Connection to search service failed content: application/json: schema: @@ -2501,18 +2281,24 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to search service failed + "201": + description: Created a new table + content: + application/json: + schema: + $ref: "#/components/schemas/TableBriefDto" + "503": + description: Failed to save in search service content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "201": - description: Created a new table + "404": + description: "Database, container or user could not be found" content: application/json: schema: - $ref: "#/components/schemas/TableBriefDto" + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -2544,7 +2330,7 @@ paths: - container-endpoint summary: Create container description: Creates a container in the metadata database. Requires role `create-container`. - operationId: create_9 + operationId: create_8 requestBody: content: application/json: @@ -2552,12 +2338,6 @@ paths: $ref: "#/components/schemas/CreateContainerDto" required: true responses: - "409": - description: Container name already exists - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "403": description: "Create container not permitted, need authority `create-container`" content: @@ -2570,8 +2350,8 @@ paths: application/json: schema: $ref: "#/components/schemas/ContainerDto" - "400": - description: Container payload malformed + "409": + description: Container name already exists content: application/json: schema: @@ -2582,9 +2362,39 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "400": + description: Container payload malformed + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] + /api/user: + get: + tags: + - user-endpoint + summary: List users + description: "Lists users known to the metadata database. Internal users are\ + \ omitted from the result list. If the optional query parameter `username`\ + \ is present, the result list can be filtered by matching this exact username." + operationId: findAll + parameters: + - name: username + in: query + required: false + schema: + type: string + responses: + "200": + description: List users + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/UserBriefDto" /api/unit: get: tags: @@ -2608,14 +2418,14 @@ paths: summary: Find entities description: Finds semantic entities by label or uri in an ontology with id. Requires role `execute-semantic-query`. - operationId: find_4 + operationId: find_5 parameters: - name: ontologyId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: label in: query required: false @@ -2627,20 +2437,22 @@ paths: schema: type: string responses: - "422": - description: Ontology does not have rdf or sparql endpoint + "200": + description: Found entities content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" + type: array + items: + $ref: "#/components/schemas/EntityDto" "400": description: Filter params are invalid content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Could not find ontology + "422": + description: Ontology does not have rdf or sparql endpoint content: application/json: schema: @@ -2651,14 +2463,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "200": - description: Found entities + "404": + description: Could not find ontology content: application/json: schema: - type: array - items: - $ref: "#/components/schemas/EntityDto" + $ref: "#/components/schemas/ApiErrorDto" security: - bearerAuth: [] - basicAuth: [] @@ -2687,27 +2497,27 @@ paths: - message-endpoint summary: Find message description: Finds a message with id in the metadata database. - operationId: find_5 + operationId: find_6 parameters: - name: messageId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "200": - description: Get messages - content: - application/json: - schema: - $ref: "#/components/schemas/BannerMessageDto" "404": description: Could not find message content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "200": + description: Get messages + content: + application/json: + schema: + $ref: "#/components/schemas/BannerMessageDto" /api/license: get: tags: @@ -2739,18 +2549,18 @@ paths: schema: type: string responses: - "404": - description: Failed to find metadata for identifier - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": description: Retrieved metadata from identifier content: application/json: schema: $ref: "#/components/schemas/IdentifierDto" + "404": + description: Failed to find metadata for identifier + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" /api/database/{databaseId}: get: tags: @@ -2763,21 +2573,9 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "404": - description: "Database, user or exchange could not be found" - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "403": - description: Not allowed to view database - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" "200": description: Database found successfully headers: @@ -2794,14 +2592,14 @@ paths: application/json: schema: $ref: "#/components/schemas/DatabaseBriefDto" - "503": - description: Failed to find queue information in broker service + "403": + description: Not allowed to view database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "502": - description: Connection to the broker service could not be established + "404": + description: Database could not be found content: application/json: schema: @@ -2822,23 +2620,17 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "403": - description: Not the table owner. - content: - application/json: - schema: - $ref: "#/components/schemas/ApiErrorDto" - "422": - description: Ontology does not have rdf or sparql endpoint + "417": + description: Generated query is malformed content: application/json: schema: @@ -2851,8 +2643,8 @@ paths: type: array items: $ref: "#/components/schemas/EntityDto" - "417": - description: Generated query is malformed + "400": + description: Failed to parse statistic in search service content: application/json: schema: @@ -2863,8 +2655,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "400": - description: Failed to parse statistic in search service + "422": + description: Ontology does not have rdf or sparql endpoint + content: + application/json: + schema: + $ref: "#/components/schemas/ApiErrorDto" + "403": + description: Not the table owner. content: application/json: schema: @@ -2884,23 +2682,23 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: columnId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "422": - description: Ontology does not have rdf or sparql endpoint + "400": + description: Generated query is malformed content: application/json: schema: @@ -2913,14 +2711,14 @@ paths: type: array items: $ref: "#/components/schemas/TableColumnEntityDto" - "400": - description: Generated query is malformed + "404": + description: Failed to find database/table in metadata database content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "404": - description: Failed to find database/table in metadata database + "422": + description: Ontology does not have rdf or sparql endpoint content: application/json: schema: @@ -2940,21 +2738,21 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: - "404": - description: Container image could not be found + "200": + description: Found container content: application/json: schema: - $ref: "#/components/schemas/ApiErrorDto" - "200": - description: Found container + $ref: "#/components/schemas/ContainerDto" + "404": + description: Container image could not be found content: application/json: schema: - $ref: "#/components/schemas/ContainerDto" + $ref: "#/components/schemas/ApiErrorDto" delete: tags: - container-endpoint @@ -2966,8 +2764,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: "403": description: "Create container not permitted, need authority `delete-container`" @@ -2975,14 +2773,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" + "202": + description: Deleted container "404": description: Container not found content: application/json: schema: $ref: "#/components/schemas/ApiErrorDto" - "202": - description: Deleted container security: - bearerAuth: [] - basicAuth: [] @@ -3004,6 +2802,145 @@ paths: $ref: "#/components/schemas/ConceptDto" components: schemas: + ApiErrorDto: + required: + - code + - message + - status + type: object + properties: + status: + type: string + example: NOT_FOUND + enum: + - 100 CONTINUE + - 101 SWITCHING_PROTOCOLS + - 102 PROCESSING + - 103 EARLY_HINTS + - 103 CHECKPOINT + - 200 OK + - 201 CREATED + - 202 ACCEPTED + - 203 NON_AUTHORITATIVE_INFORMATION + - 204 NO_CONTENT + - 205 RESET_CONTENT + - 206 PARTIAL_CONTENT + - 207 MULTI_STATUS + - 208 ALREADY_REPORTED + - 226 IM_USED + - 300 MULTIPLE_CHOICES + - 301 MOVED_PERMANENTLY + - 302 FOUND + - 302 MOVED_TEMPORARILY + - 303 SEE_OTHER + - 304 NOT_MODIFIED + - 305 USE_PROXY + - 307 TEMPORARY_REDIRECT + - 308 PERMANENT_REDIRECT + - 400 BAD_REQUEST + - 401 UNAUTHORIZED + - 402 PAYMENT_REQUIRED + - 403 FORBIDDEN + - 404 NOT_FOUND + - 405 METHOD_NOT_ALLOWED + - 406 NOT_ACCEPTABLE + - 407 PROXY_AUTHENTICATION_REQUIRED + - 408 REQUEST_TIMEOUT + - 409 CONFLICT + - 410 GONE + - 411 LENGTH_REQUIRED + - 412 PRECONDITION_FAILED + - 413 PAYLOAD_TOO_LARGE + - 413 REQUEST_ENTITY_TOO_LARGE + - 414 URI_TOO_LONG + - 414 REQUEST_URI_TOO_LONG + - 415 UNSUPPORTED_MEDIA_TYPE + - 416 REQUESTED_RANGE_NOT_SATISFIABLE + - 417 EXPECTATION_FAILED + - 418 I_AM_A_TEAPOT + - 419 INSUFFICIENT_SPACE_ON_RESOURCE + - 420 METHOD_FAILURE + - 421 DESTINATION_LOCKED + - 422 UNPROCESSABLE_ENTITY + - 423 LOCKED + - 424 FAILED_DEPENDENCY + - 425 TOO_EARLY + - 426 UPGRADE_REQUIRED + - 428 PRECONDITION_REQUIRED + - 429 TOO_MANY_REQUESTS + - 431 REQUEST_HEADER_FIELDS_TOO_LARGE + - 451 UNAVAILABLE_FOR_LEGAL_REASONS + - 500 INTERNAL_SERVER_ERROR + - 501 NOT_IMPLEMENTED + - 502 BAD_GATEWAY + - 503 SERVICE_UNAVAILABLE + - 504 GATEWAY_TIMEOUT + - 505 HTTP_VERSION_NOT_SUPPORTED + - 506 VARIANT_ALSO_NEGOTIATES + - 507 INSUFFICIENT_STORAGE + - 508 LOOP_DETECTED + - 509 BANDWIDTH_LIMIT_EXCEEDED + - 510 NOT_EXTENDED + - 511 NETWORK_AUTHENTICATION_REQUIRED + message: + type: string + example: Error message + code: + type: string + example: error.service.code + UserAttributesDto: + required: + - language + - theme + type: object + properties: + theme: + type: string + example: light + orcid: + type: string + example: https://orcid.org/0000-0002-1825-0097 + affiliation: + type: string + example: Brown University + language: + type: string + example: en + UserDto: + required: + - attributes + - id + - password + - username + type: object + properties: + id: + type: string + format: uuid + example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 + name: + type: string + example: Josiah Carberry + username: + type: string + example: username + password: + type: string + example: p4ssw0rd + attributes: + $ref: "#/components/schemas/UserAttributesDto" + last_retrieved: + type: string + format: date-time + qualified_name: + type: string + example: Josiah Carberry — @jcarberry + given_name: + type: string + example: Josiah + family_name: + type: string + example: Carberry CreatorBriefDto: required: - creator_name @@ -3011,9 +2948,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 11 + type: string + format: uuid + example: e41f94a6-2b94-4a12-ac0e-678684e1c070 affiliation: type: string example: Brown University @@ -3060,9 +2997,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc name: type: string example: Air Quality @@ -3094,6 +3031,7 @@ components: required: - creators - database_id + - descriptions - id - owned_by - publication_year @@ -3104,9 +3042,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: b97cd56b-66ca-4354-9e6c-f47210cfaaec type: type: string example: database @@ -3123,6 +3061,10 @@ components: type: array items: $ref: "#/components/schemas/IdentifierTitleDto" + descriptions: + type: array + items: + $ref: "#/components/schemas/IdentifierDescriptionDto" doi: type: string example: 10.1038/nphys1170 @@ -3136,21 +3078,18 @@ components: - draft - published database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc query_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid view_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid publication_year: type: integer format: int32 @@ -3159,18 +3098,18 @@ components: type: string format: uuid example: 2f45ef7a-7f9b-4667-9156-152c87fe1ca5 - IdentifierTitleDto: + IdentifierDescriptionDto: required: - id type: object properties: id: - type: integer - format: int64 - example: 4 - title: type: string - example: Airquality Demonstrator + format: uuid + example: e0e9692c-910b-4b60-b53a-fc7c358a917d + description: + type: string + example: "Air quality reports at Stephansplatz, Vienna" language: type: string example: en @@ -3361,570 +3300,29 @@ components: - zu type: type: string + example: Abstract enum: - - AlternativeTitle - - Subtitle - - TranslatedTitle + - Abstract + - Methods + - SeriesInformation + - TableOfContents + - TechnicalInfo - Other - UserBriefDto: + IdentifierTitleDto: required: - id - - username type: object properties: id: type: string format: uuid - example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 - username: - type: string - description: Only contains lowercase characters - example: jcarberry - name: - type: string - example: Josiah Carberry - orcid: - type: string - example: 0000-0002-1825-0097 - qualified_name: - type: string - example: Josiah Carberry — @jcarberry - given_name: - type: string - example: Josiah - family_name: + example: 70ce5164-fd74-413f-8712-f996b91defbf + title: type: string - example: Carberry - DatabaseAccessDto: - required: - - type - - user - type: object - properties: - user: - $ref: "#/components/schemas/UserBriefDto" - type: - type: string - example: read - enum: - - read - - write_own - - write_all - ApiErrorDto: - required: - - code - - message - - status - type: object - properties: - status: - type: string - example: NOT_FOUND - enum: - - 100 CONTINUE - - 101 SWITCHING_PROTOCOLS - - 102 PROCESSING - - 103 EARLY_HINTS - - 103 CHECKPOINT - - 200 OK - - 201 CREATED - - 202 ACCEPTED - - 203 NON_AUTHORITATIVE_INFORMATION - - 204 NO_CONTENT - - 205 RESET_CONTENT - - 206 PARTIAL_CONTENT - - 207 MULTI_STATUS - - 208 ALREADY_REPORTED - - 226 IM_USED - - 300 MULTIPLE_CHOICES - - 301 MOVED_PERMANENTLY - - 302 FOUND - - 302 MOVED_TEMPORARILY - - 303 SEE_OTHER - - 304 NOT_MODIFIED - - 305 USE_PROXY - - 307 TEMPORARY_REDIRECT - - 308 PERMANENT_REDIRECT - - 400 BAD_REQUEST - - 401 UNAUTHORIZED - - 402 PAYMENT_REQUIRED - - 403 FORBIDDEN - - 404 NOT_FOUND - - 405 METHOD_NOT_ALLOWED - - 406 NOT_ACCEPTABLE - - 407 PROXY_AUTHENTICATION_REQUIRED - - 408 REQUEST_TIMEOUT - - 409 CONFLICT - - 410 GONE - - 411 LENGTH_REQUIRED - - 412 PRECONDITION_FAILED - - 413 PAYLOAD_TOO_LARGE - - 413 REQUEST_ENTITY_TOO_LARGE - - 414 URI_TOO_LONG - - 414 REQUEST_URI_TOO_LONG - - 415 UNSUPPORTED_MEDIA_TYPE - - 416 REQUESTED_RANGE_NOT_SATISFIABLE - - 417 EXPECTATION_FAILED - - 418 I_AM_A_TEAPOT - - 419 INSUFFICIENT_SPACE_ON_RESOURCE - - 420 METHOD_FAILURE - - 421 DESTINATION_LOCKED - - 422 UNPROCESSABLE_ENTITY - - 423 LOCKED - - 424 FAILED_DEPENDENCY - - 425 TOO_EARLY - - 426 UPGRADE_REQUIRED - - 428 PRECONDITION_REQUIRED - - 429 TOO_MANY_REQUESTS - - 431 REQUEST_HEADER_FIELDS_TOO_LARGE - - 451 UNAVAILABLE_FOR_LEGAL_REASONS - - 500 INTERNAL_SERVER_ERROR - - 501 NOT_IMPLEMENTED - - 502 BAD_GATEWAY - - 503 SERVICE_UNAVAILABLE - - 504 GATEWAY_TIMEOUT - - 505 HTTP_VERSION_NOT_SUPPORTED - - 506 VARIANT_ALSO_NEGOTIATES - - 507 INSUFFICIENT_STORAGE - - 508 LOOP_DETECTED - - 509 BANDWIDTH_LIMIT_EXCEEDED - - 510 NOT_EXTENDED - - 511 NETWORK_AUTHENTICATION_REQUIRED - message: - type: string - example: Error message - code: - type: string - example: error.service.code - UserUpdateDto: - required: - - language - - theme - type: object - properties: - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: - type: string - example: Brown University - orcid: - type: string - example: 0000-0002-1825-0097 - theme: - type: string - example: dark - language: - type: string - example: en - UserAttributesDto: - required: - - language - - theme - type: object - properties: - theme: - type: string - example: light - orcid: - type: string - example: https://orcid.org/0000-0002-1825-0097 - affiliation: - type: string - example: Brown University - language: - type: string - example: en - UserDto: - required: - - attributes - - id - - password - - username - type: object - properties: - id: - type: string - format: uuid - example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 - name: - type: string - example: Josiah Carberry - username: - type: string - example: username - password: - type: string - example: p4ssw0rd - attributes: - $ref: "#/components/schemas/UserAttributesDto" - last_retrieved: - type: string - format: date-time - qualified_name: - type: string - example: Josiah Carberry — @jcarberry - given_name: - type: string - example: Josiah - family_name: - type: string - example: Carberry - UserPasswordDto: - required: - - password - type: object - properties: - password: - type: string - RefreshTokenRequestDto: - required: - - refresh_token - type: object - properties: - refresh_token: - type: string - example: refresh_token - TokenDto: - required: - - access_token - - expires_in - - id_token - - not-before-policy - - refresh_expires_in - - refresh_token - - scope - - session_state - - token_type - type: object - properties: - scope: - type: string - access_token: - type: string - expires_in: - type: integer - format: int64 - refresh_token: - type: string - refresh_expires_in: - type: integer - format: int64 - id_token: - type: string - session_state: - type: string - token_type: - type: string - not-before-policy: - type: integer - format: int64 - OntologyModifyDto: - required: - - prefix - - uri - type: object - properties: - uri: - type: string - example: Ontology URI - prefix: - type: string - example: Ontology prefix - sparql_endpoint: - type: string - example: Ontology SPARQL endpoint - rdf_path: - type: string - example: rdf/om-2.0.rdf - OntologyDto: - required: - - id - - prefix - - rdf - - sparql - - uri - type: object - properties: - id: - type: integer - format: int64 - uri: - type: string - example: http://www.wikidata.org/ - prefix: - type: string - example: wd - sparql: - type: boolean - example: true - rdf: - type: boolean - example: false - uri_pattern: - type: string - example: http://www.wikidata.org/entity/.* - sparql_endpoint: - type: string - example: https://query.wikidata.org/sparql - rdf_path: - type: string - example: rdf/om-2.0.rdf - BannerMessageUpdateDto: - required: - - message - - type - type: object - properties: - type: - type: string - enum: - - error - - warning - - info - message: - type: string - example: Maintenance starts on 8am on Monday - link: - type: string - example: https://example.com - link_text: - type: string - example: More - display_start: - type: string - format: date-time - example: 2021-03-12T15:26:21Z - display_end: - type: string - format: date-time - example: 2021-03-12T15:26:21Z - BannerMessageBriefDto: - required: - - message - - type - type: object - properties: - type: - type: string - enum: - - error - - warning - - info - message: - type: string - example: Maintenance starts on 8am on Monday - link: - type: string - example: https://example.com - link_text: - type: string - example: More - ImageChangeDto: - required: - - dialect - - driver_class - - jdbc_method - - registry - type: object - properties: - registry: - type: string - example: docker.io/library - defaultPort: - maximum: 65535 - minimum: 1024 - type: integer - format: int32 - example: 5432 - dialect: - type: string - example: Postgres - driver_class: - type: string - example: org.postgresql.Driver - jdbc_method: - type: string - example: postgresql - DataTypeDto: - required: - - display_name - - documentation - - is_buildable - - is_quoted - - value - type: object - properties: - value: - type: string - example: time - documentation: - type: string - example: https://mariadb.com/kb/en/time/ - display_name: - type: string - example: TIME(fsp) - size_min: - type: integer - format: int32 - example: 0 - size_max: - type: integer - format: int32 - example: 6 - size_default: - type: integer - format: int32 - example: 0 - size_required: - type: boolean - example: false - d_min: - type: integer - format: int32 - d_max: - type: integer - format: int32 - d_default: - type: integer - format: int32 - d_required: - type: boolean - data_hint: - type: string - example: "e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S" - type_hint: - type: string - example: "fsp=microsecond precision, min. 0, max. 6" - is_quoted: - type: boolean - description: frontend needs to quote this data type - example: false - is_buildable: - type: boolean - description: frontend can build this data type - example: true - ImageDto: - required: - - data_types - - default - - default_port - - dialect - - driver_class - - id - - jdbc_method - - name - - operators - - registry - - version - type: object - properties: - id: - type: integer - format: int64 - example: 1 - registry: - type: string - example: docker.io/library - name: - type: string - example: mariadb - version: - type: string - example: "10.5" - dialect: - type: string - example: org.hibernate.dialect.MariaDBDialect - operators: - type: array - items: - $ref: "#/components/schemas/OperatorDto" - driver_class: - type: string - example: org.mariadb.jdbc.Driver - jdbc_method: - type: string - example: mariadb - default: - type: boolean - example: false - default_port: - type: integer - format: int32 - example: 3306 - data_types: - type: array - items: - $ref: "#/components/schemas/DataTypeDto" - OperatorDto: - required: - - display_name - - documentation - - value - type: object - properties: - id: - type: integer - format: int64 - value: - type: string - example: XOR - documentation: - type: string - example: https://mariadb.com/kb/en/xor/ - display_name: - type: string - example: XOR - IdentifierSaveDto: - required: - - creators - - database_id - - id - - publication_year - - publisher - - titles - - type - type: object - properties: - id: - type: integer - format: int64 - example: 1 - type: - type: string - example: database - enum: - - database - - subset - - table - - view - doi: - type: string - example: 10.1111/11111111 - titles: - type: array - items: - $ref: "#/components/schemas/SaveIdentifierTitleDto" - descriptions: - type: array - items: - $ref: "#/components/schemas/SaveIdentifierDescriptionDto" - funders: - type: array - items: - $ref: "#/components/schemas/SaveIdentifierFunderDto" - licenses: - type: array - items: - $ref: "#/components/schemas/LicenseDto" - publisher: - type: string - example: TU Wien - language: + example: Airquality Demonstrator + language: type: string + example: en enum: - ab - aa @@ -4110,122 +3508,371 @@ components: - yo - za - zu - creators: - type: array - items: - $ref: "#/components/schemas/SaveIdentifierCreatorDto" - database_id: + type: + type: string + enum: + - AlternativeTitle + - Subtitle + - TranslatedTitle + - Other + UserBriefDto: + required: + - id + - username + type: object + properties: + id: + type: string + format: uuid + example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 + username: + type: string + description: Only contains lowercase characters + example: jcarberry + name: + type: string + example: Josiah Carberry + orcid: + type: string + example: 0000-0002-1825-0097 + qualified_name: + type: string + example: Josiah Carberry — @jcarberry + given_name: + type: string + example: Josiah + family_name: + type: string + example: Carberry + DatabaseAccessDto: + required: + - type + - user + type: object + properties: + user: + $ref: "#/components/schemas/UserBriefDto" + type: + type: string + example: read + enum: + - read + - write_own + - write_all + UserUpdateDto: + required: + - language + - theme + type: object + properties: + firstname: + type: string + example: Josiah + lastname: + type: string + example: Carberry + affiliation: + type: string + example: Brown University + orcid: + type: string + example: 0000-0002-1825-0097 + theme: + type: string + example: dark + language: + type: string + example: en + OntologyModifyDto: + required: + - prefix + - uri + type: object + properties: + uri: + type: string + example: Ontology URI + prefix: + type: string + example: Ontology prefix + sparql_endpoint: + type: string + example: Ontology SPARQL endpoint + rdf_path: + type: string + example: rdf/om-2.0.rdf + OntologyDto: + required: + - id + - prefix + - rdf + - sparql + - uri + type: object + properties: + id: + type: string + format: uuid + example: 7c491e40-082a-47b8-b82c-51d03c520466 + uri: + type: string + example: http://www.wikidata.org/ + prefix: + type: string + example: wd + sparql: + type: boolean + example: true + rdf: + type: boolean + example: false + uri_pattern: + type: string + example: http://www.wikidata.org/entity/.* + sparql_endpoint: + type: string + example: https://query.wikidata.org/sparql + rdf_path: + type: string + example: rdf/om-2.0.rdf + BannerMessageUpdateDto: + required: + - message + - type + type: object + properties: + type: + type: string + enum: + - error + - warning + - info + message: + type: string + example: Maintenance starts on 8am on Monday + link: + type: string + example: https://example.com + link_text: + type: string + example: More + display_start: + type: string + format: date-time + example: 2021-03-12T15:26:21Z + display_end: + type: string + format: date-time + example: 2021-03-12T15:26:21Z + BannerMessageBriefDto: + required: + - message + - type + type: object + properties: + type: + type: string + enum: + - error + - warning + - info + message: + type: string + example: Maintenance starts on 8am on Monday + link: + type: string + example: https://example.com + link_text: + type: string + example: More + ImageChangeDto: + required: + - dialect + - driver_class + - jdbc_method + - registry + type: object + properties: + registry: + type: string + example: docker.io/library + defaultPort: + maximum: 65535 + minimum: 1024 type: integer - format: int64 - example: 1 - query_id: + format: int32 + example: 5432 + dialect: + type: string + example: Postgres + driver_class: + type: string + example: org.postgresql.Driver + jdbc_method: + type: string + example: postgresql + DataTypeDto: + required: + - display_name + - documentation + - id + - is_buildable + - is_quoted + - value + type: object + properties: + id: + type: string + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcca + value: + type: string + example: time + documentation: + type: string + example: https://mariadb.com/kb/en/time/ + display_name: + type: string + example: TIME(fsp) + size_min: type: integer - format: int64 - view_id: + format: int32 + example: 0 + size_max: type: integer - format: int64 - table_id: + format: int32 + example: 6 + size_default: type: integer - format: int64 - publication_day: + format: int32 + example: 0 + size_required: + type: boolean + example: false + d_min: type: integer format: int32 - example: 15 - publication_month: + d_max: type: integer format: int32 - example: 12 - publication_year: + d_default: type: integer format: int32 - example: 2022 - related_identifiers: - type: array - items: - $ref: "#/components/schemas/SaveRelatedIdentifierDto" - LicenseDto: + d_required: + type: boolean + data_hint: + type: string + example: "e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S" + type_hint: + type: string + example: "fsp=microsecond precision, min. 0, max. 6" + is_quoted: + type: boolean + description: frontend needs to quote this data type + example: false + is_buildable: + type: boolean + description: frontend can build this data type + example: true + ImageDto: required: - - identifier - - uri + - data_types + - default + - id + - name + - operators + - version type: object properties: - identifier: + id: type: string - example: MIT - uri: + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcce + name: type: string - example: https://opensource.org/licenses/MIT - description: + example: mariadb + version: type: string - example: "A short and simple permissive license with conditions only requiring\ - \ preservation of copyright and license notices. Licensed works, modifications,\ - \ and larger works may be distributed under different terms and without\ - \ source code." - SaveIdentifierCreatorDto: + example: "10.5" + operators: + type: array + items: + $ref: "#/components/schemas/OperatorDto" + default: + type: boolean + example: false + data_types: + type: array + items: + $ref: "#/components/schemas/DataTypeDto" + OperatorDto: required: - - creator_name + - display_name + - documentation - id + - value type: object properties: id: - type: integer - format: int64 - example: 1 - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: - type: string - example: Wesleyan University - creator_name: - type: string - example: "Carberry, Josiah" - name_type: - type: string - example: Personal - enum: - - Personal - - Organizational - name_identifier: type: string - example: 0000-0002-1825-0097 - name_identifier_scheme: + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dccf + value: type: string - example: ORCID - enum: - - ORCID - - ROR - - ISNI - - GRID - affiliation_identifier: + example: XOR + documentation: type: string - example: https://ror.org/04d836q62 - affiliation_identifier_scheme: + example: https://mariadb.com/kb/en/xor/ + display_name: type: string - example: ROR - enum: - - ROR - - GRID - - ISNI - SaveIdentifierDescriptionDto: + example: XOR + IdentifierSaveDto: required: - - description + - creators + - database_id - id + - publication_year + - publisher + - titles + - type type: object properties: id: - type: integer - format: int64 - example: 1 - description: type: string - example: "Air quality reports at Stephansplatz, Vienna" + format: uuid + example: 68e11675-1e0f-4d24-a6d9-887ad1c4445d + type: + type: string + example: database + enum: + - database + - subset + - table + - view + doi: + type: string + example: 10.1111/11111111 + titles: + type: array + items: + $ref: "#/components/schemas/SaveIdentifierTitleDto" + descriptions: + type: array + items: + $ref: "#/components/schemas/SaveIdentifierDescriptionDto" + funders: + type: array + items: + $ref: "#/components/schemas/SaveIdentifierFunderDto" + licenses: + type: array + items: + $ref: "#/components/schemas/LicenseDto" + publisher: + type: string + example: TU Wien language: type: string - example: en enum: - ab - aa @@ -4411,63 +4058,118 @@ components: - yo - za - zu - type: + creators: + type: array + items: + $ref: "#/components/schemas/SaveIdentifierCreatorDto" + database_id: + type: string + format: uuid + query_id: + type: string + format: uuid + view_id: + type: string + format: uuid + table_id: + type: string + format: uuid + publication_day: + type: integer + format: int32 + example: 15 + publication_month: + type: integer + format: int32 + example: 12 + publication_year: + type: integer + format: int32 + example: 2022 + related_identifiers: + type: array + items: + $ref: "#/components/schemas/SaveRelatedIdentifierDto" + LicenseDto: + required: + - identifier + - uri + type: object + properties: + identifier: type: string - example: Abstract - enum: - - Abstract - - Methods - - SeriesInformation - - TableOfContents - - TechnicalInfo - - Other - SaveIdentifierFunderDto: + example: MIT + uri: + type: string + example: https://opensource.org/licenses/MIT + description: + type: string + example: "A short and simple permissive license with conditions only requiring\ + \ preservation of copyright and license notices. Licensed works, modifications,\ + \ and larger works may be distributed under different terms and without\ + \ source code." + SaveIdentifierCreatorDto: required: - - funder_name + - creator_name - id type: object properties: id: - type: integer - format: int64 - example: 1 - funder_name: type: string - example: European Commission - funder_identifier: + format: uuid + example: da9dd034-00a8-4517-b93d-d1b2adfee418 + firstname: type: string - example: http://doi.org/10.13039/501100000780 - funder_identifier_type: + example: Josiah + lastname: type: string - example: Crossref Funder ID + example: Carberry + affiliation: + type: string + example: Wesleyan University + creator_name: + type: string + example: "Carberry, Josiah" + name_type: + type: string + example: Personal enum: - - Crossref Funder ID + - Personal + - Organizational + name_identifier: + type: string + example: 0000-0002-1825-0097 + name_identifier_scheme: + type: string + example: ORCID + enum: + - ORCID - ROR - - GND - ISNI - - Other - scheme_uri: - type: string - example: http://doi.org/ - award_number: + - GRID + affiliation_identifier: type: string - example: "824087" - award_title: + example: https://ror.org/04d836q62 + affiliation_identifier_scheme: type: string - example: EOSC-Life - SaveIdentifierTitleDto: + example: ROR + enum: + - ROR + - GRID + - ISNI + SaveIdentifierDescriptionDto: required: + - description - id - - title type: object properties: id: - type: integer - format: int64 - example: 1 - title: type: string - example: Airquality Demonstrator + format: uuid + example: 35bd84d8-b181-43c8-b786-4d024e4f843c + description: + type: string + example: "Air quality reports at Stephansplatz, Vienna" language: type: string example: en @@ -4658,154 +4360,61 @@ components: - zu type: type: string - example: Subtitle + example: Abstract enum: - - AlternativeTitle - - Subtitle - - TranslatedTitle + - Abstract + - Methods + - SeriesInformation + - TableOfContents + - TechnicalInfo - Other - SaveRelatedIdentifierDto: - required: - - id - - relation - - type - - value - type: object - properties: - id: - type: integer - format: int64 - example: 1 - value: - type: string - example: 10.70124/dc4zh-9ce78 - type: - type: string - example: DOI - enum: - - DOI - - URL - - URN - - ARK - - arXiv - - bibcode - - EAN13 - - EISSN - - Handle - - IGSN - - ISBN - - ISTC - - LISSN - - LSID - - PMID - - PURL - - UPC - - w3id - relation: - type: string - example: Cites - enum: - - IsCitedBy - - Cites - - IsSupplementTo - - IsSupplementedBy - - IsContinuedBy - - Continues - - IsDescribedBy - - Describes - - HasMetadata - - IsMetadataFor - - HasVersion - - IsVersionOf - - IsNewVersionOf - - IsPreviousVersionOf - - IsPartOf - - HasPart - - IsPublishedIn - - IsReferencedBy - - References - - IsDocumentedBy - - Documents - - IsCompiledBy - - Compiles - - IsVariantFormOf - - IsOriginalFormOf - - IsIdenticalTo - - IsReviewedBy - - Reviews - - IsDerivedFrom - - IsSourceOf - - IsRequiredBy - - Requires - - IsObsoletedBy - - Obsoletes - CreatorDto: + SaveIdentifierFunderDto: required: - - creator_name + - funder_name - id type: object properties: id: - type: integer - format: int64 - example: 11 - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: type: string - example: Brown University - creator_name: - type: string - example: "Carberry, Josiah" - name_type: + format: uuid + example: 1c6b9212-a315-44b9-946c-3682a7a0e517 + funder_name: type: string - example: Personal - enum: - - Personal - - Organizational - name_identifier: + example: European Commission + funder_identifier: type: string - example: 0000-0002-1825-0097 - name_identifier_scheme: + example: http://doi.org/10.13039/501100000780 + funder_identifier_type: type: string - example: ORCID + example: Crossref Funder ID enum: - - ORCID + - Crossref Funder ID - ROR + - GND - ISNI - - GRID - name_identifier_scheme_uri: - type: string - example: https://orcid.org/ - affiliation_identifier: + - Other + scheme_uri: type: string - example: https://ror.org/05gq02987 - affiliation_identifier_scheme: + example: http://doi.org/ + award_number: type: string - example: ROR - enum: - - ROR - - GRID - - ISNI - affiliation_identifier_scheme_uri: + example: "824087" + award_title: type: string - example: https://ror.org/ - IdentifierDescriptionDto: + example: EOSC-Life + SaveIdentifierTitleDto: required: - id + - title type: object properties: id: - type: integer - format: int64 - example: 3 - description: type: string - example: "Air quality reports at Stephansplatz, Vienna" + format: uuid + example: 2af9f40e-eaf5-4ea1-861a-1a696587bf29 + title: + type: string + example: Airquality Demonstrator language: type: string example: en @@ -4996,14 +4605,142 @@ components: - zu type: type: string - example: Abstract + example: Subtitle + enum: + - AlternativeTitle + - Subtitle + - TranslatedTitle + - Other + SaveRelatedIdentifierDto: + required: + - id + - relation + - type + - value + type: object + properties: + id: + type: string + format: uuid + example: 5bb272c7-7421-4f74-83ac-0486812d0f44 + value: + type: string + example: 10.70124/dc4zh-9ce78 + type: + type: string + example: DOI enum: - - Abstract - - Methods - - SeriesInformation - - TableOfContents - - TechnicalInfo - - Other + - DOI + - URL + - URN + - ARK + - arXiv + - bibcode + - EAN13 + - EISSN + - Handle + - IGSN + - ISBN + - ISTC + - LISSN + - LSID + - PMID + - PURL + - UPC + - w3id + relation: + type: string + example: Cites + enum: + - IsCitedBy + - Cites + - IsSupplementTo + - IsSupplementedBy + - IsContinuedBy + - Continues + - IsDescribedBy + - Describes + - HasMetadata + - IsMetadataFor + - HasVersion + - IsVersionOf + - IsNewVersionOf + - IsPreviousVersionOf + - IsPartOf + - HasPart + - IsPublishedIn + - IsReferencedBy + - References + - IsDocumentedBy + - Documents + - IsCompiledBy + - Compiles + - IsVariantFormOf + - IsOriginalFormOf + - IsIdenticalTo + - IsReviewedBy + - Reviews + - IsDerivedFrom + - IsSourceOf + - IsRequiredBy + - Requires + - IsObsoletedBy + - Obsoletes + CreatorDto: + required: + - creator_name + - id + type: object + properties: + id: + type: string + format: uuid + example: e41f94a6-2b94-4a12-ac0e-678684e1c070 + firstname: + type: string + example: Josiah + lastname: + type: string + example: Carberry + affiliation: + type: string + example: Brown University + creator_name: + type: string + example: "Carberry, Josiah" + name_type: + type: string + example: Personal + enum: + - Personal + - Organizational + name_identifier: + type: string + example: 0000-0002-1825-0097 + name_identifier_scheme: + type: string + example: ORCID + enum: + - ORCID + - ROR + - ISNI + - GRID + name_identifier_scheme_uri: + type: string + example: https://orcid.org/ + affiliation_identifier: + type: string + example: https://ror.org/05gq02987 + affiliation_identifier_scheme: + type: string + example: ROR + enum: + - ROR + - GRID + - ISNI + affiliation_identifier_scheme_uri: + type: string + example: https://ror.org/ IdentifierDto: required: - creators @@ -5025,9 +4762,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: b97cd56b-66ca-4354-9e6c-f47210cfaaec type: type: string example: database @@ -5266,21 +5003,17 @@ components: - draft - published database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid query_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid view_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid query_normalized: type: string example: "SELECT `id`, `value`, `location` FROM `air_quality` WHERE `location`\ @@ -5318,9 +5051,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 39693413-e0ce-46da-ad5e-029c0556d439 funder_name: type: string example: European Commission @@ -5354,9 +5087,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: ce9d11f0-60a2-448d-a3e4-44719a443e8a value: type: string example: 10.70124/dc4zh-9ce78 @@ -5455,9 +5188,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 787439d0-e85e-400c-a7e6-996a023bfad9 name: type: string example: Air Quality @@ -5465,9 +5198,9 @@ components: type: string example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 2b5b2b03-fdd0-40d6-afe0-e5d02fd839e4 internal_name: type: string example: air_quality @@ -5518,9 +5251,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: 41ed10e0-687b-4e18-8521-810f5cffbce1 name: type: string example: Air Quality @@ -5528,9 +5261,9 @@ components: type: string example: Air Quality in Austria database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: a8fec026-dfaf-4b1d-8f6c-f01720d91705 internal_name: type: string example: air_quality @@ -5567,9 +5300,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: a453e444-e00d-41ca-902c-11e9c54b39f1 name: maxLength: 64 minLength: 0 @@ -5603,26 +5336,20 @@ components: example: Column comment enums: type: array - example: - - val1 items: - type: string - example: "[\"val1\"]" + $ref: "#/components/schemas/EnumDto" sets: type: array - example: - - val1 items: - type: string - example: "[\"val1\"]" + $ref: "#/components/schemas/SetDto" database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 911f9052-c58c-4e1c-b3f2-66af2107be16 table_id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: bfffa915-a547-4466-9c65-ddc0d38fdb08 ord: type: integer format: int32 @@ -5705,9 +5432,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 23 + type: string + format: uuid + example: 8cabc011-4bdf-44d4-9d33-b2648e2ddbf1 uri: type: string example: http://www.wikidata.org/entity/Q202444 @@ -5718,6 +5445,32 @@ components: type: string example: "name typically used to differentiate people from the same family,\ \ clan, or other social group who have a common last name" + EnumDto: + required: + - id + - value + type: object + properties: + id: + type: string + format: uuid + example: 5343bb3d-14d3-4eb7-a86f-b8fc553cb315 + value: + type: string + example: "3" + SetDto: + required: + - id + - value + type: object + properties: + id: + type: string + format: uuid + example: 7eb4eded-bacc-4a91-84db-a9ae6ddafda7 + value: + type: string + example: "3" UnitBriefDto: required: - id @@ -5725,9 +5478,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 34 + type: string + format: uuid + example: ba1935e8-6817-488f-af0a-f54389af9000 uri: type: string example: http://www.wikidata.org/entity/Q1422583 @@ -5762,33 +5515,6 @@ components: - read - write_own - write_all - CreateUserDto: - required: - - email - - password - - username - type: object - properties: - username: - pattern: "^[a-z0-9]{3,}$" - type: string - example: user - email: - type: string - example: user@example.com - password: - type: string - LoginRequestDto: - required: - - password - - username - type: object - properties: - username: - type: string - example: user - password: - type: string OntologyCreateDto: required: - prefix @@ -6099,18 +5825,18 @@ components: items: $ref: "#/components/schemas/SaveIdentifierCreatorDto" database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: d002e8d5-8db4-4ff7-ab3a-bc3f52d9ec44 query_id: - type: integer - format: int64 - view_id: - type: integer - format: int64 + type: string + format: uuid + view_id: + type: string + format: uuid table_id: - type: integer - format: int64 + type: string + format: uuid publication_day: type: integer format: int32 @@ -6139,9 +5865,9 @@ components: type: string example: Air Quality container_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 0888e108-d521-46e2-9d3e-82099185305b is_public: type: boolean example: true @@ -6162,14 +5888,79 @@ components: type: string example: Air Quality query: - type: string - example: SELECT `id` FROM `air_quality` + $ref: "#/components/schemas/SubsetDto" is_public: type: boolean example: true is_schema_public: type: boolean example: true + FilterDto: + required: + - column_id + - operator_id + - type + - value + type: object + properties: + type: + type: string + example: where + enum: + - where + - or + - and + value: + type: string + example: "1" + column_id: + type: string + format: uuid + example: 14128033-54b5-4818-a489-21b0dded86e2 + operator_id: + type: string + format: uuid + example: 67c5b54d-2eb0-4f42-8dc1-a504562e9f32 + OrderDto: + required: + - column_id + type: object + properties: + direction: + type: string + example: asc + enum: + - asc + - desc + column_id: + type: string + format: uuid + example: e891ba86-0258-41a6-a8d9-ff58bc10b618 + SubsetDto: + required: + - columns + - table_id + type: object + properties: + columns: + type: array + example: + - e891ba86-0258-41a6-a8d9-ff58bc10b618 + items: + type: string + format: uuid + filter: + type: array + items: + $ref: "#/components/schemas/FilterDto" + order: + type: array + items: + $ref: "#/components/schemas/OrderDto" + table_id: + type: string + format: uuid + example: f7df2a7d-4ade-4c78-97b0-7c744d0893c7 CreateForeignKeyDto: required: - columns @@ -6179,16 +5970,24 @@ components: properties: columns: type: array + example: + - id items: type: string + example: "[\"id\"]" referenced_table: type: string + example: sensor referenced_columns: type: array + example: + - other_id items: type: string + example: "[\"other_id\"]" on_update: type: string + example: cascade enum: - restrict - cascade @@ -6197,6 +5996,7 @@ components: - set_default on_delete: type: string + example: cascade enum: - restrict - cascade @@ -6215,7 +6015,7 @@ components: example: Date type: type: string - example: string + example: varchar enum: - char - varchar @@ -6368,10 +6168,10 @@ components: format: int64 example: 50 image_id: - type: integer + type: string description: Image ID - format: int64 - example: 1 + format: uuid + example: 2360f3c4-85e0-4fac-a7c6-73b296b9dde2 ui_host: type: string example: example.com @@ -6394,23 +6194,15 @@ components: - image - internal_name - name - - quota type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 7ddb7e87-b965-43a2-9a24-4fa406d998f4 name: type: string example: Air Quality - host: - type: string - example: data-db - port: - type: integer - format: int32 - example: 3306 image: $ref: "#/components/schemas/ImageDto" quota: @@ -6433,13 +6225,6 @@ components: internal_name: type: string example: air_quality - ui_host: - type: string - example: example.com - ui_port: - type: integer - format: int32 - example: 3306 ColumnBriefDto: required: - database_id @@ -6451,9 +6236,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: a453e444-e00d-41ca-902c-11e9c54b39f1 name: maxLength: 64 minLength: 0 @@ -6463,13 +6248,13 @@ components: type: string example: firstname database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 911f9052-c58c-4e1c-b3f2-66af2107be16 table_id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: bfffa915-a547-4466-9c65-ddc0d38fdb08 internal_name: maxLength: 64 minLength: 0 @@ -6517,8 +6302,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: ba1935e8-6817-488f-af0a-f54389af9000 uri: type: string name: @@ -6539,8 +6325,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: 7c491e40-082a-47b8-b82c-51d03c520466 uri: type: string example: http://www.wikidata.org/ @@ -6600,10 +6387,12 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: ae3f795b-a3da-4ebe-bdc4-21a8ce631e6f type: type: string + example: WARNING enum: - error - warning @@ -6629,24 +6418,20 @@ components: required: - default - id - - jdbc_method - name - version type: object properties: id: - type: integer - format: int64 - example: 5 + type: string + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcce name: type: string example: mariadb version: type: string example: "10.5" - jdbc_method: - type: string - example: mariadb default: type: boolean example: false @@ -6712,6 +6497,153 @@ components: type: string '@type': type: string + ViewColumnDto: + required: + - database_id + - id + - internal_name + - is_null_allowed + - name + - ord + - type + type: object + properties: + id: + type: string + format: uuid + example: 6aec3a91-2e0b-4e92-a16a-9c3c5e892da1 + name: + maxLength: 64 + minLength: 0 + type: string + example: Given Name + size: + type: integer + format: int64 + example: 255 + d: + type: integer + format: int64 + example: 0 + description: + maxLength: 2048 + minLength: 0 + type: string + example: Column comment + database_id: + type: string + format: uuid + example: 2b5b2b03-fdd0-40d6-afe0-e5d02fd839e4 + ord: + type: integer + format: int32 + example: 0 + internal_name: + maxLength: 64 + minLength: 0 + type: string + example: given_name + index_length: + type: integer + format: int64 + example: 255 + length: + type: integer + format: int64 + example: 255 + type: + type: string + example: varchar + enum: + - char + - varchar + - binary + - varbinary + - tinyblob + - tinytext + - text + - blob + - mediumtext + - mediumblob + - longtext + - longblob + - enum + - set + - serial + - bit + - tinyint + - bool + - smallint + - mediumint + - int + - bigint + - float + - double + - decimal + - date + - datetime + - timestamp + - time + - year + is_null_allowed: + type: boolean + example: false + ViewDto: + required: + - columns + - database_id + - id + - identifiers + - internal_name + - name + - owner + - query + - query_hash + type: object + properties: + id: + type: string + format: uuid + example: 787439d0-e85e-400c-a7e6-996a023bfad9 + name: + type: string + example: Air Quality + identifiers: + type: array + items: + $ref: "#/components/schemas/IdentifierDto" + query: + type: string + example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC + owner: + $ref: "#/components/schemas/UserBriefDto" + columns: + type: array + items: + $ref: "#/components/schemas/ViewColumnDto" + last_retrieved: + type: string + format: date-time + database_id: + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc + internal_name: + type: string + example: air_quality + is_public: + type: boolean + example: true + is_schema_public: + type: boolean + example: true + initial_view: + type: boolean + description: True if it is the default view for the database + example: true + query_hash: + type: string + example: 7de03e818900b6ea6d58ad0306d4a741d658c6df3d1964e89ed2395d8c7e7916 ConstraintsDto: type: object properties: @@ -6736,86 +6668,13 @@ components: type: array items: $ref: "#/components/schemas/PrimaryKeyDto" - DatabaseDto: - required: - - accesses - - contact - - exchange_name - - id - - identifiers - - internal_name - - is_public - - is_schema_public - - name - - owner - - subsets - - tables - - views - type: object - properties: - id: - type: integer - format: int64 - example: 3 - name: - type: string - example: Air Quality - description: - type: string - example: Air Quality - tables: - type: array - items: - $ref: "#/components/schemas/TableDto" - views: - type: array - items: - $ref: "#/components/schemas/ViewDto" - container: - $ref: "#/components/schemas/ContainerDto" - accesses: - type: array - items: - $ref: "#/components/schemas/DatabaseAccessDto" - identifiers: - type: array - items: - $ref: "#/components/schemas/IdentifierDto" - subsets: - type: array - items: - $ref: "#/components/schemas/IdentifierDto" - contact: - $ref: "#/components/schemas/UserBriefDto" - owner: - $ref: "#/components/schemas/UserBriefDto" - last_retrieved: - type: string - format: date-time - exchange_name: - type: string - example: dbrepo - exchange_type: - type: string - example: topic - internal_name: - type: string - example: air_quality - is_public: - type: boolean - example: true - is_schema_public: - type: boolean - example: true - preview_image: - type: string ForeignKeyBriefDto: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a ForeignKeyDto: required: - name @@ -6825,9 +6684,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a name: type: string example: fk_name @@ -6865,9 +6724,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a column: $ref: "#/components/schemas/ColumnBriefDto" foreign_key: @@ -6881,9 +6740,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: d984f9d7-e8a7-4b81-b59a-862db1871f18 table: $ref: "#/components/schemas/TableBriefDto" column: @@ -6905,9 +6764,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: d346f844-b84c-490f-9aec-725a2dc8f820 name: type: string example: Air Quality @@ -6929,17 +6788,15 @@ components: type: array items: $ref: "#/components/schemas/ColumnDto" - database: - $ref: "#/components/schemas/DatabaseDto" constraints: $ref: "#/components/schemas/ConstraintsDto" last_retrieved: type: string format: date-time database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc internal_name: type: string example: air_quality @@ -6989,9 +6846,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 5 + type: string + format: uuid + example: d984f9d7-e8a7-4b81-b59a-862db1871f13 name: type: string example: uk_name @@ -7001,155 +6858,6 @@ components: type: array items: $ref: "#/components/schemas/ColumnBriefDto" - ViewColumnDto: - required: - - database_id - - id - - internal_name - - is_null_allowed - - name - - ord - - type - type: object - properties: - id: - type: integer - format: int64 - example: 12 - name: - maxLength: 64 - minLength: 0 - type: string - example: Given Name - size: - type: integer - format: int64 - example: 255 - d: - type: integer - format: int64 - example: 0 - description: - maxLength: 2048 - minLength: 0 - type: string - example: Column comment - database_id: - type: integer - format: int64 - example: 1 - ord: - type: integer - format: int32 - example: 0 - internal_name: - maxLength: 64 - minLength: 0 - type: string - example: given_name - index_length: - type: integer - format: int64 - example: 255 - length: - type: integer - format: int64 - example: 255 - type: - type: string - example: varchar - enum: - - char - - varchar - - binary - - varbinary - - tinyblob - - tinytext - - text - - blob - - mediumtext - - mediumblob - - longtext - - longblob - - enum - - set - - serial - - bit - - tinyint - - bool - - smallint - - mediumint - - int - - bigint - - float - - double - - decimal - - date - - datetime - - timestamp - - time - - year - is_null_allowed: - type: boolean - example: false - ViewDto: - required: - - columns - - database_id - - id - - identifiers - - internal_name - - name - - owner - - query - - query_hash - type: object - properties: - id: - type: integer - format: int64 - example: 4 - name: - type: string - example: Air Quality - identifiers: - type: array - items: - $ref: "#/components/schemas/IdentifierDto" - query: - type: string - example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC - database: - $ref: "#/components/schemas/DatabaseDto" - owner: - $ref: "#/components/schemas/UserBriefDto" - columns: - type: array - items: - $ref: "#/components/schemas/ViewColumnDto" - last_retrieved: - type: string - format: date-time - database_id: - type: integer - format: int64 - example: 1 - internal_name: - type: string - example: air_quality - is_public: - type: boolean - example: true - is_schema_public: - type: boolean - example: true - initial_view: - type: boolean - description: True if it is the default view for the database - example: true - query_hash: - type: string - example: 7de03e818900b6ea6d58ad0306d4a741d658c6df3d1964e89ed2395d8c7e7916 TableColumnEntityDto: required: - column_id @@ -7168,17 +6876,17 @@ components: type: string example: open source semantic web framework for Java database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 475b4107-a64d-4495-a7ef-3cb0dadd4804 table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 9a9208af-90ea-4382-9a11-0c8f6d89bd1f column_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 297860e3-3b29-451c-ae8a-a85ed5941018 ContainerBriefDto: required: - count @@ -7191,9 +6899,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 7ddb7e87-b965-43a2-9a24-4fa406d998f4 hash: type: string example: f829dd8a884182d0da846f365dee1221fd16610a14c81b8f9f295ff162749e50 @@ -7221,8 +6929,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: 8cabc011-4bdf-44d4-9d33-b2648e2ddbf1 uri: type: string name: diff --git a/.docs/.openapi/api.yaml b/.docs/.openapi/api.yaml index c23937c6e72cdc9a8b8956b34aeeec63bfd15ce2..8c5ea7a152b470d31b4dd950b661684d3c83fda2 100644 --- a/.docs/.openapi/api.yaml +++ b/.docs/.openapi/api.yaml @@ -16,7 +16,7 @@ info: name: Apache 2.0 url: 'https://www.apache.org/licenses/LICENSE-2.0' title: DBRepo REST API - version: 1.7.2 + version: 1.7.0 servers: - description: Test Instance url: 'https://test.dbrepo.tuwien.ac.at' @@ -153,22 +153,21 @@ paths: summary: Get view data description: >- Gets data from a view of a database. For private databases, the user - needs at least *READ* access to the associated database. Requires role - `view-database-view-data`. + needs at least *READ* access to the associated database. operationId: getData parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: page in: query required: false @@ -242,22 +241,21 @@ paths: summary: Get view data description: >- Gets data from a view of a database. For private databases, the user - needs at least *READ* access to the associated database. Requires role - `view-database-view-data`. + needs at least *READ* access to the associated database. operationId: getData_1 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: page in: query required: false @@ -341,14 +339,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -424,14 +422,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -487,14 +485,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -552,14 +550,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -616,14 +614,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -702,14 +700,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -795,14 +793,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -884,14 +882,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: queryId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -956,14 +954,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Authorization in: header required: true @@ -1022,8 +1020,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: persisted in: query required: false @@ -1076,8 +1074,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -1100,7 +1098,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ExecuteStatementDto' + $ref: '#/components/schemas/SubsetDto' required: true responses: '201': @@ -1165,14 +1163,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -1229,14 +1227,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: size in: query required: false @@ -1294,14 +1292,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: timestamp in: query required: false @@ -1360,14 +1358,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: subsetId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true @@ -1422,101 +1420,131 @@ paths: security: - basicAuth: [] - bearerAuth: [] - /api/database: + '/api/user/{userId}': get: tags: - - database-endpoint - summary: List databases + - user-endpoint + summary: Get user description: >- - Lists all databases in the metadata database. Requests with HTTP method - **GET** return the list of databases, requests with HTTP method **HEAD** - only the number in the `X-Count` header. - operationId: list1 + Gets own user information from the metadata database. Requires + authentication. Foreign user information can only be obtained if + additional role `find-foreign-user` is present. Finding information + about internal users results in a 404 error. + operationId: find parameters: - - name: internal_name - in: query - required: false + - name: userId + in: path + required: true schema: type: string + format: uuid responses: '200': - description: List of databases - headers: - Access-Control-Expose-Headers: - description: Expose `X-Count` custom header - required: true - style: simple - X-Count: - description: Number of databases - required: true - style: simple + description: Found user content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/DatabaseBriefDto' - post: + $ref: '#/components/schemas/UserDto' + '403': + description: Find user is not permitted + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '404': + description: User was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + security: + - bearerAuth: [] + - basicAuth: [] + put: tags: - - database-endpoint - summary: Create database - description: >- - Creates a database in the container with id. Requires roles - `create-database`. - operationId: create_5 + - user-endpoint + summary: Update user + description: Updates user with id. Requires role `modify-user-information`. + operationId: modify + parameters: + - name: userId + in: path + required: true + schema: + type: string + format: uuid requestBody: content: application/json: schema: - $ref: '#/components/schemas/CreateDatabaseDto' + $ref: '#/components/schemas/UserUpdateDto' required: true responses: - '201': - description: Created a new database + '202': + description: Modified user information content: application/json: schema: - $ref: '#/components/schemas/DatabaseBriefDto' + $ref: '#/components/schemas/UserDto' '400': - description: Database create query is malformed or image is not supported + description: Modify user query is malformed content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' '403': - description: >- - Database create permission is missing or grant permissions at broker - service failed + description: Not allowed to modify user metadata content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' '404': - description: Failed to fin container/user/database in metadata database + description: Failed to find database/user in metadata database content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '409': - description: Query store could not be created + '503': + description: Failed to modify user at auth service content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '423': - description: Database quota exceeded + security: + - bearerAuth: [] + - basicAuth: [] + head: + tags: + - user-endpoint + summary: Get user + description: >- + Gets own user information from the metadata database. Requires + authentication. Foreign user information can only be obtained if + additional role `find-foreign-user` is present. Finding information + about internal users results in a 404 error. + operationId: find_1 + parameters: + - name: userId + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: Found user content: application/json: schema: - $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Connection to search service failed + $ref: '#/components/schemas/UserDto' + '403': + description: Find user is not permitted content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to save in search service + '404': + description: User was not found content: application/json: schema: @@ -1524,7 +1552,109 @@ paths: security: - bearerAuth: [] - basicAuth: [] - head: + /api/database: + get: + tags: + - database-endpoint + summary: List databases + description: >- + Lists all databases in the metadata database. Requests with HTTP method + **GET** return the list of databases, requests with HTTP method **HEAD** + only the number in the `X-Count` header. + operationId: list1 + parameters: + - name: internal_name + in: query + required: false + schema: + type: string + responses: + '200': + description: List of databases + headers: + Access-Control-Expose-Headers: + description: Expose `X-Count` custom header + required: true + style: simple + X-Count: + description: Number of databases + required: true + style: simple + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/DatabaseBriefDto' + post: + tags: + - database-endpoint + summary: Create database + description: >- + Creates a database in the container with id. Requires roles + `create-database`. + operationId: create_4 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDatabaseDto' + required: true + responses: + '201': + description: Created a new database + content: + application/json: + schema: + $ref: '#/components/schemas/DatabaseBriefDto' + '400': + description: Database create query is malformed or image is not supported + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '403': + description: >- + Database create permission is missing or grant permissions at broker + service failed + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '404': + description: Failed to fin container/user/database in metadata database + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '409': + description: Query store could not be created + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '423': + description: Database quota exceeded + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '502': + description: Connection to search service failed + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + '503': + description: Failed to save in search service + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' + security: + - bearerAuth: [] + - basicAuth: [] + head: tags: - database-endpoint summary: List databases @@ -1568,14 +1698,14 @@ paths: with HTTP method **HEAD** only the status. When the user has at least *READ* access, the status 200 is returned, 403 otherwise. Requires role `check-database-access` or `check-foreign-database-access`. - operationId: find + operationId: find_2 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -1617,8 +1747,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -1678,14 +1808,14 @@ paths: description: >- Give a user with given id access to some database with given id. Requires role `create-database-access`. - operationId: create_8 + operationId: create_7 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -1751,8 +1881,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -1805,14 +1935,14 @@ paths: with HTTP method **HEAD** only the status. When the user has at least *READ* access, the status 200 is returned, 403 otherwise. Requires role `check-database-access` or `check-foreign-database-access`. - operationId: find_1 + operationId: find_3 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: userId in: path required: true @@ -1841,19 +1971,15 @@ paths: security: - bearerAuth: [] - basicAuth: [] - '/api/user/{userId}': + '/api/ontology/{ontologyId}': get: tags: - - user-endpoint - summary: Get user - description: >- - Gets own user information from the metadata database. Requires - authentication. Foreign user information can only be obtained if - additional role `find-foreign-user` is present. Finding information - about internal users results in a 404 error. - operationId: find_2 + - ontology-endpoint + summary: Find ontology + description: Finds an ontology with id in the metadata database. + operationId: find_4 parameters: - - name: userId + - name: ontologyId in: path required: true schema: @@ -1861,34 +1987,25 @@ paths: format: uuid responses: '200': - description: Found user - content: - application/json: - schema: - $ref: '#/components/schemas/UserDto' - '403': - description: Find user is not permitted + description: Find one ontology content: application/json: schema: - $ref: '#/components/schemas/ApiErrorDto' + $ref: '#/components/schemas/OntologyDto' '404': - description: User was not found + description: Could not find ontology content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - security: - - bearerAuth: [] - - basicAuth: [] put: tags: - - user-endpoint - summary: Update user - description: Updates user with id. Requires role `modify-user-information`. - operationId: modify + - ontology-endpoint + summary: Update ontology + description: Updates an ontology with id. Requires role `update-ontology`. + operationId: update parameters: - - name: userId + - name: ontologyId in: path required: true schema: @@ -1898,29 +2015,44 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UserUpdateDto' + $ref: '#/components/schemas/OntologyModifyDto' required: true responses: '202': - description: Modified user information + description: Updated ontology successfully content: application/json: schema: - $ref: '#/components/schemas/UserDto' - '400': - description: Modify user query is malformed + $ref: '#/components/schemas/OntologyDto' + '404': + description: Could not find ontology content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '403': - description: Not allowed to modify user metadata + security: + - bearerAuth: [] + - basicAuth: [] + delete: + tags: + - ontology-endpoint + summary: Delete ontology + description: Deletes an ontology with given id. Requires role `delete-ontology`. + operationId: delete + parameters: + - name: ontologyId + in: path + required: true + schema: + type: string + format: uuid + responses: + '202': + description: Deleted ontology successfully content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' + application/json: {} '404': - description: Failed to find database/user in metadata database + description: Could not find ontology content: application/json: schema: @@ -1928,15 +2060,15 @@ paths: security: - bearerAuth: [] - basicAuth: [] - '/api/user/{userId}/password': + '/api/message/{messageId}': put: tags: - - user-endpoint - summary: Update user password - description: Updates password of user with id. Requires authentication. - operationId: password + - message-endpoint + summary: Update message + description: Updates a message with id. Requires role `update-maintenance-message`. + operationId: update_1 parameters: - - name: userId + - name: messageId in: path required: true schema: @@ -1946,37 +2078,44 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UserPasswordDto' + $ref: '#/components/schemas/BannerMessageUpdateDto' required: true responses: '202': - description: Modified user password - '400': - description: Invalid password payload - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '403': - description: Not allowed to change foreign user password + description: Updated message content: application/json: schema: - $ref: '#/components/schemas/ApiErrorDto' + $ref: '#/components/schemas/BannerMessageBriefDto' '404': - description: Failed to find database/user in metadata database + description: Could not find message content: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Connection to auth service failed + security: + - bearerAuth: [] + - basicAuth: [] + delete: + tags: + - message-endpoint + summary: Delete message + description: Deletes a message with id. Requires role `delete-maintenance-message`. + operationId: delete_1 + parameters: + - name: messageId + in: path + required: true + schema: + type: string + format: uuid + responses: + '202': + description: Deleted message content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to get user in auth service + application/json: {} + '404': + description: Could not find message content: application/json: schema: @@ -1984,255 +2123,8 @@ paths: security: - bearerAuth: [] - basicAuth: [] - /api/user/token: - put: - tags: - - user-endpoint - summary: Refresh token - description: Refreshes user token by refresh token. - operationId: refreshToken - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/RefreshTokenRequestDto' - required: true - responses: - '202': - description: Refreshed user token - content: - application/json: - schema: - $ref: '#/components/schemas/TokenDto' - '400': - description: Invalid refresh token - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '403': - description: Not allowed - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Connection to auth service failed - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - post: - tags: - - user-endpoint - summary: Create token - description: Creates a user token via the Auth Service. - operationId: getToken - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/LoginRequestDto' - required: true - responses: - '202': - description: Obtained user token - content: - application/json: - schema: - $ref: '#/components/schemas/TokenDto' - '400': - description: Invalid login request - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '403': - description: Not allowed to get token - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '404': - description: Failed to find user in auth database - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '428': - description: >- - Account is not fully setup in auth service (requires password - change?) - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Connection to auth service failed - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to get user in auth service - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '/api/ontology/{ontologyId}': - get: - tags: - - ontology-endpoint - summary: Find ontology - description: Finds an ontology with id in the metadata database. - operationId: find_3 - parameters: - - name: ontologyId - in: path - required: true - schema: - type: integer - format: int64 - responses: - '200': - description: Find one ontology - content: - application/json: - schema: - $ref: '#/components/schemas/OntologyDto' - '404': - description: Could not find ontology - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - put: - tags: - - ontology-endpoint - summary: Update ontology - description: Updates an ontology with id. Requires role `update-ontology`. - operationId: update - parameters: - - name: ontologyId - in: path - required: true - schema: - type: integer - format: int64 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/OntologyModifyDto' - required: true - responses: - '202': - description: Updated ontology successfully - content: - application/json: - schema: - $ref: '#/components/schemas/OntologyDto' - '404': - description: Could not find ontology - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - security: - - bearerAuth: [] - - basicAuth: [] - delete: - tags: - - ontology-endpoint - summary: Delete ontology - description: Deletes an ontology with given id. Requires role `delete-ontology`. - operationId: delete - parameters: - - name: ontologyId - in: path - required: true - schema: - type: integer - format: int64 - responses: - '202': - description: Deleted ontology successfully - content: - application/json: {} - '404': - description: Could not find ontology - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - security: - - bearerAuth: [] - - basicAuth: [] - '/api/message/{messageId}': - put: - tags: - - message-endpoint - summary: Update message - description: Updates a message with id. Requires role `update-maintenance-message`. - operationId: update_1 - parameters: - - name: messageId - in: path - required: true - schema: - type: integer - format: int64 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/BannerMessageUpdateDto' - required: true - responses: - '202': - description: Updated message - content: - application/json: - schema: - $ref: '#/components/schemas/BannerMessageBriefDto' - '404': - description: Could not find message - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - security: - - bearerAuth: [] - - basicAuth: [] - delete: - tags: - - message-endpoint - summary: Delete message - description: Deletes a message with id. Requires role `delete-maintenance-message`. - operationId: delete_1 - parameters: - - name: messageId - in: path - required: true - schema: - type: integer - format: int64 - responses: - '202': - description: Deleted message - content: - application/json: {} - '404': - description: Could not find message - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - security: - - bearerAuth: [] - - basicAuth: [] - '/api/image/{imageId}': - get: + '/api/image/{imageId}': + get: tags: - image-endpoint summary: Find image @@ -2243,8 +2135,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Found image @@ -2271,8 +2163,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2308,8 +2200,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Deleted image successfully @@ -2330,14 +2222,14 @@ paths: description: >- Finds an identifier with id. The response format depends on the HTTP `Accept` header set on the request. - operationId: find_6 + operationId: find_7 parameters: - name: identifierId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true @@ -2365,6 +2257,12 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' + '403': + description: Not allowed to view identifier + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' '404': description: Identifier could not be found content: @@ -2416,8 +2314,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2475,8 +2373,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Deleted identifier @@ -2521,8 +2419,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Published identifier @@ -2577,8 +2475,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2631,48 +2529,23 @@ paths: - view-endpoint summary: Get view description: Gets a view with id in the metadata database. - operationId: find_7 + operationId: find_8 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Find view successfully - headers: - X-Username: - description: The authentication username - style: simple - Access-Control-Expose-Headers: - description: Expose custom headers - style: simple - X-Type: - description: The JDBC connection type - style: simple - X-View: - description: The view internal name - style: simple - X-Database: - description: The database internal name - style: simple - X-Password: - description: The authentication password - style: simple - X-Host: - description: The database hostname - style: simple - X-Port: - description: The database port number - style: simple content: application/json: schema: @@ -2705,14 +2578,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2770,14 +2643,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: viewId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Delete view successfully @@ -2836,27 +2709,17 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Find table successfully - headers: - X-Username: - description: The authentication username - style: simple - Access-Control-Expose-Headers: - description: Expose custom headers - style: simple - X-Password: - description: The authentication password - style: simple content: application/json: schema: @@ -2873,18 +2736,6 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Failed to establish connection with broker service - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to obtain queue information from broker service - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' security: - bearerAuth: [] - basicAuth: [] @@ -2899,14 +2750,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -2967,14 +2818,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Delete table successfully @@ -3026,14 +2877,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Updated table statistics successfully @@ -3086,20 +2937,20 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: columnId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -3162,8 +3013,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -3225,8 +3076,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Refreshed database views metadata @@ -3276,8 +3127,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Refreshed database tables metadata @@ -3298,7 +3149,7 @@ paths: schema: $ref: '#/components/schemas/ApiErrorDto' '404': - description: Failed to fin user/database in metadata database + description: Failed to find database in metadata database content: application/json: schema: @@ -3330,8 +3181,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: View of image was successful @@ -3364,8 +3215,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -3412,93 +3263,6 @@ paths: security: - bearerAuth: [] - basicAuth: [] - /api/user: - get: - tags: - - user-endpoint - summary: List users - description: >- - Lists users known to the metadata database. Internal users are omitted - from the result list. If the optional query parameter `username` is - present, the result list can be filtered by matching this exact - username. - operationId: findAll - parameters: - - name: username - in: query - required: false - schema: - type: string - responses: - '200': - description: List users - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/UserBriefDto' - post: - tags: - - user-endpoint - summary: Create user - description: >- - Creates a user in the auth service and metadata database. Requires that - no credentials are sent in the request. - operationId: create1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateUserDto' - required: true - responses: - '201': - description: Created user - content: - application/json: - schema: - $ref: '#/components/schemas/UserDto' - '400': - description: Parameters are not well-formed (likely email) - content: - application/json: {} - '403': - description: Internal authentication to the auth service is invalid - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '404': - description: Default role not found - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '409': - description: User with username already exists - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '417': - description: User with e-mail already exists - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Failed to create in auth service - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to create in auth service - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' /api/ontology: get: tags: @@ -3522,7 +3286,7 @@ paths: description: >- Creates an ontology in the metadata database. Requires role `create-ontology`. - operationId: create_1 + operationId: create1 requestBody: content: application/json: @@ -3573,7 +3337,7 @@ paths: description: >- Creates a message in the metadata database. Requires role `create-maintenance-message`. - operationId: create_2 + operationId: create_1 requestBody: content: application/json: @@ -3613,7 +3377,7 @@ paths: description: >- Creates a container image in the metadata database. Requires role `create-image`. - operationId: create_3 + operationId: create_2 requestBody: content: application/json: @@ -3650,30 +3414,48 @@ paths: description: Lists all identifiers known to the metadata database operationId: findAll_4 parameters: + - name: type + in: query + required: false + schema: + type: string + enum: + - database + - subset + - table + - view + - name: status + in: query + required: false + schema: + type: string + enum: + - draft + - published - name: dbid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: qid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: vid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: tid in: query required: false schema: - type: integer - format: int64 + type: string + format: uuid - name: Accept in: header required: true @@ -3693,12 +3475,6 @@ paths: type: array items: $ref: '#/components/schemas/LdDatasetDto' - '406': - description: 'Identifier could not be exported, the requested style is not known' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' post: tags: - identifier-endpoint @@ -3708,7 +3484,7 @@ paths: can only be created for objects the user has at least *READ* access in the associated database (requires role `create-identifier`) or for any object in any database (requires role `create-foreign-identifier`). - operationId: create_4 + operationId: create_3 requestBody: content: application/json: @@ -3767,8 +3543,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Find views successfully @@ -3794,14 +3570,14 @@ paths: description: >- Creates a view. This can only be performed by the database owner. Requires role `create-database-view`. - operationId: create_6 + operationId: create_5 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -3833,6 +3609,12 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiErrorDto' + '409': + description: View exists with name + content: + application/json: + schema: + $ref: '#/components/schemas/ApiErrorDto' '423': description: Create view resulted in an invalid query statement content: @@ -3869,8 +3651,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: List tables @@ -3900,14 +3682,14 @@ paths: - table-endpoint summary: Create table description: Creates a table in the database with id. Requires role `create-table`. - operationId: create_7 + operationId: create_6 parameters: - name: databaseId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid requestBody: content: application/json: @@ -3990,7 +3772,7 @@ paths: description: >- Creates a container in the metadata database. Requires role `create-container`. - operationId: create_9 + operationId: create_8 requestBody: content: application/json: @@ -4031,6 +3813,32 @@ paths: security: - bearerAuth: [] - basicAuth: [] + /api/user: + get: + tags: + - user-endpoint + summary: List users + description: >- + Lists users known to the metadata database. Internal users are omitted + from the result list. If the optional query parameter `username` is + present, the result list can be filtered by matching this exact + username. + operationId: findAll + parameters: + - name: username + in: query + required: false + schema: + type: string + responses: + '200': + description: List users + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/UserBriefDto' /api/unit: get: tags: @@ -4055,14 +3863,14 @@ paths: description: >- Finds semantic entities by label or uri in an ontology with id. Requires role `execute-semantic-query`. - operationId: find_4 + operationId: find_5 parameters: - name: ontologyId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: label in: query required: false @@ -4134,14 +3942,14 @@ paths: - message-endpoint summary: Find message description: Finds a message with id in the metadata database. - operationId: find_5 + operationId: find_6 parameters: - name: messageId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Get messages @@ -4211,8 +4019,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Database found successfully @@ -4237,19 +4045,7 @@ paths: schema: $ref: '#/components/schemas/ApiErrorDto' '404': - description: 'Database, user or exchange could not be found' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '502': - description: Connection to the broker service could not be established - content: - application/json: - schema: - $ref: '#/components/schemas/ApiErrorDto' - '503': - description: Failed to find queue information in broker service + description: Database could not be found content: application/json: schema: @@ -4271,14 +4067,14 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Suggested table semantics successfully @@ -4333,20 +4129,20 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: tableId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid - name: columnId in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Suggested table column semantics successfully @@ -4389,8 +4185,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '200': description: Found container @@ -4417,8 +4213,8 @@ paths: in: path required: true schema: - type: integer - format: int64 + type: string + format: uuid responses: '202': description: Deleted container @@ -4826,9 +4622,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 11 + type: string + format: uuid + example: e41f94a6-2b94-4a12-ac0e-678684e1c070 affiliation: type: string example: Brown University @@ -4866,6 +4662,7 @@ components: required: - creators - database_id + - descriptions - id - owned_by - publication_year @@ -4876,9 +4673,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: b97cd56b-66ca-4354-9e6c-f47210cfaaec type: type: string example: database @@ -4895,6 +4692,10 @@ components: type: array items: $ref: '#/components/schemas/IdentifierTitleDto' + descriptions: + type: array + items: + $ref: '#/components/schemas/IdentifierDescriptionDto' doi: type: string example: 10.1038/nphys1170 @@ -4908,21 +4709,18 @@ components: - draft - published database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc query_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid view_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid publication_year: type: integer format: int32 @@ -4931,18 +4729,18 @@ components: type: string format: uuid example: 2f45ef7a-7f9b-4667-9156-152c87fe1ca5 - IdentifierTitleDto: + IdentifierDescriptionDto: required: - id type: object properties: id: - type: integer - format: int64 - example: 4 - title: type: string - example: Airquality Demonstrator + format: uuid + example: e0e9692c-910b-4b60-b53a-fc7c358a917d + description: + type: string + example: 'Air quality reports at Stephansplatz, Vienna' language: type: string example: en @@ -5133,119 +4931,329 @@ components: - zu type: type: string + example: Abstract enum: - - AlternativeTitle - - Subtitle - - TranslatedTitle + - Abstract + - Methods + - SeriesInformation + - TableOfContents + - TechnicalInfo - Other - QueryDto: - required: - - database_id - - execution - - id - - identifiers - - is_persisted - - owner - - query - - query_hash - - query_normalized - type: object - properties: - id: - type: integer - format: int64 - example: 4 - owner: - $ref: '#/components/schemas/UserBriefDto' - execution: - type: string - format: date-time - example: '2021-03-12T15:26:21.000Z' - query: - type: string - example: SELECT `id` FROM `air_quality` - type: - type: string - example: query - enum: - - query - - view - identifiers: - type: array - items: - $ref: '#/components/schemas/IdentifierBriefDto' - database_id: - type: integer - format: int64 - example: 1 - query_normalized: - type: string - example: SELECT `id` FROM `air_quality` - query_hash: - type: string - example: 17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76 - is_persisted: - type: boolean - example: true - result_hash: - type: string - example: 17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76 - result_number: - type: integer - format: int64 - example: 1 - UserBriefDto: + IdentifierTitleDto: required: - id - - username type: object properties: id: type: string format: uuid - example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 - username: - type: string - description: Only contains lowercase characters - example: jcarberry - name: - type: string - example: Josiah Carberry - orcid: - type: string - example: 0000-0002-1825-0097 - qualified_name: - type: string - example: Josiah Carberry — @jcarberry - given_name: - type: string - example: Josiah - family_name: + example: 70ce5164-fd74-413f-8712-f996b91defbf + title: type: string - example: Carberry - TupleDto: - required: - - data - type: object - properties: - data: - type: object - additionalProperties: - type: object - example: - key: value - example: - key: value - ImportDto: - required: - - header - - location - - separator - type: object - properties: - location: + example: Airquality Demonstrator + language: type: string - example: file.csv + example: en + enum: + - ab + - aa + - af + - ak + - sq + - am + - ar + - an + - hy + - as + - av + - ae + - ay + - az + - bm + - ba + - eu + - be + - bn + - bh + - bi + - bs + - br + - bg + - my + - ca + - km + - ch + - ce + - ny + - zh + - cu + - cv + - kw + - co + - cr + - hr + - cs + - da + - dv + - nl + - dz + - en + - eo + - et + - ee + - fo + - fj + - fi + - fr + - ff + - gd + - gl + - lg + - ka + - de + - ki + - el + - kl + - gn + - gu + - ht + - ha + - he + - hz + - hi + - ho + - hu + - is + - io + - ig + - id + - ia + - ie + - iu + - ik + - ga + - it + - ja + - jv + - kn + - kr + - ks + - kk + - rw + - kv + - kg + - ko + - kj + - ku + - ky + - lo + - la + - lv + - lb + - li + - ln + - lt + - lu + - mk + - mg + - ms + - ml + - mt + - gv + - mi + - mr + - mh + - ro + - mn + - na + - nv + - nd + - ng + - ne + - se + - 'no' + - nb + - nn + - ii + - oc + - oj + - or + - om + - os + - pi + - pa + - ps + - fa + - pl + - pt + - qu + - rm + - rn + - ru + - sm + - sg + - sa + - sc + - sr + - sn + - sd + - si + - sk + - sl + - so + - st + - nr + - es + - su + - sw + - ss + - sv + - tl + - ty + - tg + - ta + - tt + - te + - th + - bo + - ti + - to + - ts + - tn + - tr + - tk + - tw + - ug + - uk + - ur + - uz + - ve + - vi + - vo + - wa + - cy + - fy + - wo + - xh + - yi + - yo + - za + - zu + type: + type: string + enum: + - AlternativeTitle + - Subtitle + - TranslatedTitle + - Other + QueryDto: + required: + - database_id + - execution + - id + - identifiers + - is_persisted + - owner + - query + - query_hash + - query_normalized + type: object + properties: + id: + type: string + format: uuid + example: 83ea2326-f8f6-4263-baf8-cdf88a54efc7 + owner: + $ref: '#/components/schemas/UserBriefDto' + execution: + type: string + format: date-time + example: '2021-03-12T15:26:21.000Z' + query: + type: string + example: SELECT `id` FROM `air_quality` + type: + type: string + example: query + enum: + - query + - view + identifiers: + type: array + items: + $ref: '#/components/schemas/IdentifierBriefDto' + database_id: + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc + query_normalized: + type: string + example: SELECT `id` FROM `air_quality` + query_hash: + type: string + example: 17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76 + is_persisted: + type: boolean + example: true + result_hash: + type: string + example: 17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76 + result_number: + type: integer + format: int64 + example: 1 + UserBriefDto: + required: + - id + - username + type: object + properties: + id: + type: string + format: uuid + example: 1ffc7b0e-9aeb-4e8b-b8f1-68f3936155b4 + username: + type: string + description: Only contains lowercase characters + example: jcarberry + name: + type: string + example: Josiah Carberry + orcid: + type: string + example: 0000-0002-1825-0097 + qualified_name: + type: string + example: Josiah Carberry — @jcarberry + given_name: + type: string + example: Josiah + family_name: + type: string + example: Carberry + TupleDto: + required: + - data + type: object + properties: + data: + type: object + additionalProperties: + type: object + example: + key: value + example: + key: value + ImportDto: + required: + - header + - location + - separator + type: object + properties: + location: + type: string + example: file.csv header: type: boolean description: >- @@ -5261,14 +5269,72 @@ components: line_termination: type: string example: \r\n - ExecuteStatementDto: + FilterDto: required: - - statement + - column_id + - operator_id + - type + - value type: object properties: - statement: + type: type: string - example: SELECT `id` FROM `air_quality` + example: where + enum: + - where + - or + - and + value: + type: string + example: '1' + column_id: + type: string + format: uuid + example: 14128033-54b5-4818-a489-21b0dded86e2 + operator_id: + type: string + format: uuid + example: 67c5b54d-2eb0-4f42-8dc1-a504562e9f32 + OrderDto: + required: + - column_id + type: object + properties: + direction: + type: string + example: asc + enum: + - asc + - desc + column_id: + type: string + format: uuid + example: e891ba86-0258-41a6-a8d9-ff58bc10b618 + SubsetDto: + required: + - columns + - table_id + type: object + properties: + columns: + type: array + example: + - e891ba86-0258-41a6-a8d9-ff58bc10b618 + items: + type: string + format: uuid + filter: + type: array + items: + $ref: '#/components/schemas/FilterDto' + order: + type: array + items: + $ref: '#/components/schemas/OrderDto' + table_id: + type: string + format: uuid + example: f7df2a7d-4ade-4c78-97b0-7c744d0893c7 TableHistoryDto: required: - event @@ -5282,6 +5348,10 @@ components: example: '2021-03-12T15:26:21.000Z' event: type: string + example: INSERT + enum: + - insert + - delete total: type: integer format: int64 @@ -5299,88 +5369,6 @@ components: id: 1 example: id: 1 - DatabaseBriefDto: - required: - - contact - - id - - identifiers - - internal_name - - is_public - - is_schema_public - - name - - owner_id - type: object - properties: - id: - type: integer - format: int64 - example: 3 - name: - type: string - example: Air Quality - description: - type: string - example: Air Quality - identifiers: - type: array - items: - $ref: '#/components/schemas/IdentifierBriefDto' - contact: - $ref: '#/components/schemas/UserBriefDto' - internal_name: - type: string - example: air_quality - is_public: - type: boolean - example: true - is_schema_public: - type: boolean - example: true - owner_id: - type: string - format: uuid - example: 2f45ef7a-7f9b-4667-9156-152c87fe1ca5 - preview_image: - type: string - DatabaseAccessDto: - required: - - type - - user - type: object - properties: - user: - $ref: '#/components/schemas/UserBriefDto' - type: - type: string - example: read - enum: - - read - - write_own - - write_all - UserUpdateDto: - required: - - language - - theme - type: object - properties: - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: - type: string - example: Brown University - orcid: - type: string - example: 0000-0002-1825-0097 - theme: - type: string - example: dark - language: - type: string - example: en UserAttributesDto: required: - language @@ -5433,56 +5421,89 @@ components: example: Josiah family_name: type: string - example: Carberry - UserPasswordDto: - required: - - password - type: object - properties: - password: + example: Carberry + DatabaseBriefDto: + required: + - contact + - id + - identifiers + - internal_name + - is_public + - is_schema_public + - name + - owner_id + type: object + properties: + id: + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc + name: + type: string + example: Air Quality + description: + type: string + example: Air Quality + identifiers: + type: array + items: + $ref: '#/components/schemas/IdentifierBriefDto' + contact: + $ref: '#/components/schemas/UserBriefDto' + internal_name: + type: string + example: air_quality + is_public: + type: boolean + example: true + is_schema_public: + type: boolean + example: true + owner_id: + type: string + format: uuid + example: 2f45ef7a-7f9b-4667-9156-152c87fe1ca5 + preview_image: type: string - RefreshTokenRequestDto: + DatabaseAccessDto: required: - - refresh_token + - type + - user type: object properties: - refresh_token: + user: + $ref: '#/components/schemas/UserBriefDto' + type: type: string - example: refresh_token - TokenDto: + example: read + enum: + - read + - write_own + - write_all + UserUpdateDto: required: - - access_token - - expires_in - - id_token - - not-before-policy - - refresh_expires_in - - refresh_token - - scope - - session_state - - token_type + - language + - theme type: object properties: - scope: + firstname: type: string - access_token: + example: Josiah + lastname: type: string - expires_in: - type: integer - format: int64 - refresh_token: + example: Carberry + affiliation: type: string - refresh_expires_in: - type: integer - format: int64 - id_token: + example: Brown University + orcid: type: string - session_state: + example: 0000-0002-1825-0097 + theme: type: string - token_type: + example: dark + language: type: string - not-before-policy: - type: integer - format: int64 + example: en OntologyModifyDto: required: - prefix @@ -5511,8 +5532,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: 7c491e40-082a-47b8-b82c-51d03c520466 uri: type: string example: 'http://www.wikidata.org/' @@ -5525,569 +5547,253 @@ components: rdf: type: boolean example: false - uri_pattern: - type: string - example: 'http://www.wikidata.org/entity/.*' - sparql_endpoint: - type: string - example: 'https://query.wikidata.org/sparql' - rdf_path: - type: string - example: rdf/om-2.0.rdf - BannerMessageUpdateDto: - required: - - message - - type - type: object - properties: - type: - type: string - enum: - - error - - warning - - info - message: - type: string - example: Maintenance starts on 8am on Monday - link: - type: string - example: 'https://example.com' - link_text: - type: string - example: More - display_start: - type: string - format: date-time - example: '2021-03-12T15:26:21.000Z' - display_end: - type: string - format: date-time - example: '2021-03-12T15:26:21.000Z' - BannerMessageBriefDto: - required: - - message - - type - type: object - properties: - type: - type: string - enum: - - error - - warning - - info - message: - type: string - example: Maintenance starts on 8am on Monday - link: - type: string - example: 'https://example.com' - link_text: - type: string - example: More - ImageChangeDto: - required: - - dialect - - driver_class - - jdbc_method - - registry - type: object - properties: - registry: - type: string - example: docker.io/library - defaultPort: - maximum: 65535 - minimum: 1024 - type: integer - format: int32 - example: 5432 - dialect: - type: string - example: Postgres - driver_class: - type: string - example: org.postgresql.Driver - jdbc_method: - type: string - example: postgresql - DataTypeDto: - required: - - display_name - - documentation - - is_buildable - - is_quoted - - value - type: object - properties: - value: - type: string - example: time - documentation: - type: string - example: 'https://mariadb.com/kb/en/time/' - display_name: - type: string - example: TIME(fsp) - size_min: - type: integer - format: int32 - example: 0 - size_max: - type: integer - format: int32 - example: 6 - size_default: - type: integer - format: int32 - example: 0 - size_required: - type: boolean - example: false - d_min: - type: integer - format: int32 - d_max: - type: integer - format: int32 - d_default: - type: integer - format: int32 - d_required: - type: boolean - data_hint: - type: string - example: 'e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S' - type_hint: - type: string - example: 'fsp=microsecond precision, min. 0, max. 6' - is_quoted: - type: boolean - description: frontend needs to quote this data type - example: false - is_buildable: - type: boolean - description: frontend can build this data type - example: true - ImageDto: - required: - - data_types - - default - - default_port - - dialect - - driver_class - - id - - jdbc_method - - name - - operators - - registry - - version - type: object - properties: - id: - type: integer - format: int64 - example: 1 - registry: - type: string - example: docker.io/library - name: - type: string - example: mariadb - version: - type: string - example: '10.5' - dialect: - type: string - example: org.hibernate.dialect.MariaDBDialect - operators: - type: array - items: - $ref: '#/components/schemas/OperatorDto' - driver_class: - type: string - example: org.mariadb.jdbc.Driver - jdbc_method: - type: string - example: mariadb - default: - type: boolean - example: false - default_port: - type: integer - format: int32 - example: 3306 - data_types: - type: array - items: - $ref: '#/components/schemas/DataTypeDto' - OperatorDto: - required: - - display_name - - documentation - - value - type: object - properties: - id: - type: integer - format: int64 - value: + uri_pattern: type: string - example: XOR - documentation: + example: 'http://www.wikidata.org/entity/.*' + sparql_endpoint: type: string - example: 'https://mariadb.com/kb/en/xor/' - display_name: + example: 'https://query.wikidata.org/sparql' + rdf_path: type: string - example: XOR - IdentifierSaveDto: + example: rdf/om-2.0.rdf + BannerMessageUpdateDto: required: - - creators - - database_id - - id - - publication_year - - publisher - - titles + - message - type type: object properties: - id: - type: integer - format: int64 - example: 1 type: type: string - example: database enum: - - database - - subset - - table - - view - doi: + - error + - warning + - info + message: type: string - example: 10.1111/11111111 - titles: - type: array - items: - $ref: '#/components/schemas/SaveIdentifierTitleDto' - descriptions: - type: array - items: - $ref: '#/components/schemas/SaveIdentifierDescriptionDto' - funders: - type: array - items: - $ref: '#/components/schemas/SaveIdentifierFunderDto' - licenses: - type: array - items: - $ref: '#/components/schemas/LicenseDto' - publisher: + example: Maintenance starts on 8am on Monday + link: type: string - example: TU Wien - language: + example: 'https://example.com' + link_text: type: string - enum: - - ab - - aa - - af - - ak - - sq - - am - - ar - - an - - hy - - as - - av - - ae - - ay - - az - - bm - - ba - - eu - - be - - bn - - bh - - bi - - bs - - br - - bg - - my - - ca - - km - - ch - - ce - - ny - - zh - - cu - - cv - - kw - - co - - cr - - hr - - cs - - da - - dv - - nl - - dz - - en - - eo - - et - - ee - - fo - - fj - - fi - - fr - - ff - - gd - - gl - - lg - - ka - - de - - ki - - el - - kl - - gn - - gu - - ht - - ha - - he - - hz - - hi - - ho - - hu - - is - - io - - ig - - id - - ia - - ie - - iu - - ik - - ga - - it - - ja - - jv - - kn - - kr - - ks - - kk - - rw - - kv - - kg - - ko - - kj - - ku - - ky - - lo - - la - - lv - - lb - - li - - ln - - lt - - lu - - mk - - mg - - ms - - ml - - mt - - gv - - mi - - mr - - mh - - ro - - mn - - na - - nv - - nd - - ng - - ne - - se - - 'no' - - nb - - nn - - ii - - oc - - oj - - or - - om - - os - - pi - - pa - - ps - - fa - - pl - - pt - - qu - - rm - - rn - - ru - - sm - - sg - - sa - - sc - - sr - - sn - - sd - - si - - sk - - sl - - so - - st - - nr - - es - - su - - sw - - ss - - sv - - tl - - ty - - tg - - ta - - tt - - te - - th - - bo - - ti - - to - - ts - - tn - - tr - - tk - - tw - - ug - - uk - - ur - - uz - - ve - - vi - - vo - - wa - - cy - - fy - - wo - - xh - - yi - - yo - - za - - zu - creators: - type: array - items: - $ref: '#/components/schemas/SaveIdentifierCreatorDto' - database_id: + example: More + display_start: + type: string + format: date-time + example: '2021-03-12T15:26:21.000Z' + display_end: + type: string + format: date-time + example: '2021-03-12T15:26:21.000Z' + BannerMessageBriefDto: + required: + - message + - type + type: object + properties: + type: + type: string + enum: + - error + - warning + - info + message: + type: string + example: Maintenance starts on 8am on Monday + link: + type: string + example: 'https://example.com' + link_text: + type: string + example: More + ImageChangeDto: + required: + - dialect + - driver_class + - jdbc_method + - registry + type: object + properties: + registry: + type: string + example: docker.io/library + defaultPort: + maximum: 65535 + minimum: 1024 type: integer - format: int64 - example: 1 - query_id: + format: int32 + example: 5432 + dialect: + type: string + example: Postgres + driver_class: + type: string + example: org.postgresql.Driver + jdbc_method: + type: string + example: postgresql + DataTypeDto: + required: + - display_name + - documentation + - id + - is_buildable + - is_quoted + - value + type: object + properties: + id: + type: string + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcca + value: + type: string + example: time + documentation: + type: string + example: 'https://mariadb.com/kb/en/time/' + display_name: + type: string + example: TIME(fsp) + size_min: type: integer - format: int64 - view_id: + format: int32 + example: 0 + size_max: type: integer - format: int64 - table_id: + format: int32 + example: 6 + size_default: type: integer - format: int64 - publication_day: + format: int32 + example: 0 + size_required: + type: boolean + example: false + d_min: type: integer format: int32 - example: 15 - publication_month: + d_max: type: integer format: int32 - example: 12 - publication_year: + d_default: type: integer format: int32 - example: 2022 - related_identifiers: - type: array - items: - $ref: '#/components/schemas/SaveRelatedIdentifierDto' - LicenseDto: + d_required: + type: boolean + data_hint: + type: string + example: 'e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S' + type_hint: + type: string + example: 'fsp=microsecond precision, min. 0, max. 6' + is_quoted: + type: boolean + description: frontend needs to quote this data type + example: false + is_buildable: + type: boolean + description: frontend can build this data type + example: true + ImageDto: required: - - identifier - - uri + - data_types + - default + - id + - name + - operators + - version type: object properties: - identifier: + id: type: string - example: MIT - uri: + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcce + name: type: string - example: 'https://opensource.org/licenses/MIT' - description: + example: mariadb + version: type: string - example: >- - A short and simple permissive license with conditions only requiring - preservation of copyright and license notices. Licensed works, - modifications, and larger works may be distributed under different - terms and without source code. - SaveIdentifierCreatorDto: + example: '10.5' + operators: + type: array + items: + $ref: '#/components/schemas/OperatorDto' + default: + type: boolean + example: false + data_types: + type: array + items: + $ref: '#/components/schemas/DataTypeDto' + OperatorDto: required: - - creator_name + - display_name + - documentation - id + - value type: object properties: id: - type: integer - format: int64 - example: 1 - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: - type: string - example: Wesleyan University - creator_name: - type: string - example: 'Carberry, Josiah' - name_type: - type: string - example: Personal - enum: - - Personal - - Organizational - name_identifier: type: string - example: 0000-0002-1825-0097 - name_identifier_scheme: + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dccf + value: type: string - example: ORCID - enum: - - ORCID - - ROR - - ISNI - - GRID - affiliation_identifier: + example: XOR + documentation: type: string - example: 'https://ror.org/04d836q62' - affiliation_identifier_scheme: + example: 'https://mariadb.com/kb/en/xor/' + display_name: type: string - example: ROR - enum: - - ROR - - GRID - - ISNI - SaveIdentifierDescriptionDto: + example: XOR + IdentifierSaveDto: required: - - description + - creators + - database_id - id + - publication_year + - publisher + - titles + - type type: object properties: id: - type: integer - format: int64 - example: 1 - description: type: string - example: 'Air quality reports at Stephansplatz, Vienna' + format: uuid + example: 68e11675-1e0f-4d24-a6d9-887ad1c4445d + type: + type: string + example: database + enum: + - database + - subset + - table + - view + doi: + type: string + example: 10.1111/11111111 + titles: + type: array + items: + $ref: '#/components/schemas/SaveIdentifierTitleDto' + descriptions: + type: array + items: + $ref: '#/components/schemas/SaveIdentifierDescriptionDto' + funders: + type: array + items: + $ref: '#/components/schemas/SaveIdentifierFunderDto' + licenses: + type: array + items: + $ref: '#/components/schemas/LicenseDto' + publisher: + type: string + example: TU Wien language: type: string - example: en enum: - ab - aa @@ -6273,63 +5979,119 @@ components: - yo - za - zu - type: + creators: + type: array + items: + $ref: '#/components/schemas/SaveIdentifierCreatorDto' + database_id: type: string - example: Abstract - enum: - - Abstract - - Methods - - SeriesInformation - - TableOfContents - - TechnicalInfo - - Other - SaveIdentifierFunderDto: + format: uuid + query_id: + type: string + format: uuid + view_id: + type: string + format: uuid + table_id: + type: string + format: uuid + publication_day: + type: integer + format: int32 + example: 15 + publication_month: + type: integer + format: int32 + example: 12 + publication_year: + type: integer + format: int32 + example: 2022 + related_identifiers: + type: array + items: + $ref: '#/components/schemas/SaveRelatedIdentifierDto' + LicenseDto: required: - - funder_name + - identifier + - uri + type: object + properties: + identifier: + type: string + example: MIT + uri: + type: string + example: 'https://opensource.org/licenses/MIT' + description: + type: string + example: >- + A short and simple permissive license with conditions only requiring + preservation of copyright and license notices. Licensed works, + modifications, and larger works may be distributed under different + terms and without source code. + SaveIdentifierCreatorDto: + required: + - creator_name - id type: object properties: id: - type: integer - format: int64 - example: 1 - funder_name: type: string - example: European Commission - funder_identifier: + format: uuid + example: da9dd034-00a8-4517-b93d-d1b2adfee418 + firstname: type: string - example: 'http://doi.org/10.13039/501100000780' - funder_identifier_type: + example: Josiah + lastname: type: string - example: Crossref Funder ID + example: Carberry + affiliation: + type: string + example: Wesleyan University + creator_name: + type: string + example: 'Carberry, Josiah' + name_type: + type: string + example: Personal enum: - - Crossref Funder ID + - Personal + - Organizational + name_identifier: + type: string + example: 0000-0002-1825-0097 + name_identifier_scheme: + type: string + example: ORCID + enum: + - ORCID - ROR - - GND - ISNI - - Other - scheme_uri: - type: string - example: 'http://doi.org/' - award_number: + - GRID + affiliation_identifier: type: string - example: '824087' - award_title: + example: 'https://ror.org/04d836q62' + affiliation_identifier_scheme: type: string - example: EOSC-Life - SaveIdentifierTitleDto: + example: ROR + enum: + - ROR + - GRID + - ISNI + SaveIdentifierDescriptionDto: required: + - description - id - - title type: object properties: id: - type: integer - format: int64 - example: 1 - title: type: string - example: Airquality Demonstrator + format: uuid + example: 35bd84d8-b181-43c8-b786-4d024e4f843c + description: + type: string + example: 'Air quality reports at Stephansplatz, Vienna' language: type: string example: en @@ -6520,154 +6282,61 @@ components: - zu type: type: string - example: Subtitle + example: Abstract enum: - - AlternativeTitle - - Subtitle - - TranslatedTitle + - Abstract + - Methods + - SeriesInformation + - TableOfContents + - TechnicalInfo - Other - SaveRelatedIdentifierDto: - required: - - id - - relation - - type - - value - type: object - properties: - id: - type: integer - format: int64 - example: 1 - value: - type: string - example: 10.70124/dc4zh-9ce78 - type: - type: string - example: DOI - enum: - - DOI - - URL - - URN - - ARK - - arXiv - - bibcode - - EAN13 - - EISSN - - Handle - - IGSN - - ISBN - - ISTC - - LISSN - - LSID - - PMID - - PURL - - UPC - - w3id - relation: - type: string - example: Cites - enum: - - IsCitedBy - - Cites - - IsSupplementTo - - IsSupplementedBy - - IsContinuedBy - - Continues - - IsDescribedBy - - Describes - - HasMetadata - - IsMetadataFor - - HasVersion - - IsVersionOf - - IsNewVersionOf - - IsPreviousVersionOf - - IsPartOf - - HasPart - - IsPublishedIn - - IsReferencedBy - - References - - IsDocumentedBy - - Documents - - IsCompiledBy - - Compiles - - IsVariantFormOf - - IsOriginalFormOf - - IsIdenticalTo - - IsReviewedBy - - Reviews - - IsDerivedFrom - - IsSourceOf - - IsRequiredBy - - Requires - - IsObsoletedBy - - Obsoletes - CreatorDto: + SaveIdentifierFunderDto: required: - - creator_name + - funder_name - id type: object properties: id: - type: integer - format: int64 - example: 11 - firstname: - type: string - example: Josiah - lastname: - type: string - example: Carberry - affiliation: - type: string - example: Brown University - creator_name: - type: string - example: 'Carberry, Josiah' - name_type: - type: string - example: Personal - enum: - - Personal - - Organizational - name_identifier: - type: string - example: 0000-0002-1825-0097 - name_identifier_scheme: type: string - example: ORCID - enum: - - ORCID - - ROR - - ISNI - - GRID - name_identifier_scheme_uri: + format: uuid + example: 1c6b9212-a315-44b9-946c-3682a7a0e517 + funder_name: type: string - example: 'https://orcid.org/' - affiliation_identifier: + example: European Commission + funder_identifier: type: string - example: 'https://ror.org/05gq02987' - affiliation_identifier_scheme: + example: 'http://doi.org/10.13039/501100000780' + funder_identifier_type: type: string - example: ROR + example: Crossref Funder ID enum: + - Crossref Funder ID - ROR - - GRID + - GND - ISNI - affiliation_identifier_scheme_uri: + - Other + scheme_uri: type: string - example: 'https://ror.org/' - IdentifierDescriptionDto: + example: 'http://doi.org/' + award_number: + type: string + example: '824087' + award_title: + type: string + example: EOSC-Life + SaveIdentifierTitleDto: required: - id + - title type: object properties: id: - type: integer - format: int64 - example: 3 - description: type: string - example: 'Air quality reports at Stephansplatz, Vienna' + format: uuid + example: 2af9f40e-eaf5-4ea1-861a-1a696587bf29 + title: + type: string + example: Airquality Demonstrator language: type: string example: en @@ -6858,14 +6527,142 @@ components: - zu type: type: string - example: Abstract + example: Subtitle enum: - - Abstract - - Methods - - SeriesInformation - - TableOfContents - - TechnicalInfo + - AlternativeTitle + - Subtitle + - TranslatedTitle - Other + SaveRelatedIdentifierDto: + required: + - id + - relation + - type + - value + type: object + properties: + id: + type: string + format: uuid + example: 5bb272c7-7421-4f74-83ac-0486812d0f44 + value: + type: string + example: 10.70124/dc4zh-9ce78 + type: + type: string + example: DOI + enum: + - DOI + - URL + - URN + - ARK + - arXiv + - bibcode + - EAN13 + - EISSN + - Handle + - IGSN + - ISBN + - ISTC + - LISSN + - LSID + - PMID + - PURL + - UPC + - w3id + relation: + type: string + example: Cites + enum: + - IsCitedBy + - Cites + - IsSupplementTo + - IsSupplementedBy + - IsContinuedBy + - Continues + - IsDescribedBy + - Describes + - HasMetadata + - IsMetadataFor + - HasVersion + - IsVersionOf + - IsNewVersionOf + - IsPreviousVersionOf + - IsPartOf + - HasPart + - IsPublishedIn + - IsReferencedBy + - References + - IsDocumentedBy + - Documents + - IsCompiledBy + - Compiles + - IsVariantFormOf + - IsOriginalFormOf + - IsIdenticalTo + - IsReviewedBy + - Reviews + - IsDerivedFrom + - IsSourceOf + - IsRequiredBy + - Requires + - IsObsoletedBy + - Obsoletes + CreatorDto: + required: + - creator_name + - id + type: object + properties: + id: + type: string + format: uuid + example: e41f94a6-2b94-4a12-ac0e-678684e1c070 + firstname: + type: string + example: Josiah + lastname: + type: string + example: Carberry + affiliation: + type: string + example: Brown University + creator_name: + type: string + example: 'Carberry, Josiah' + name_type: + type: string + example: Personal + enum: + - Personal + - Organizational + name_identifier: + type: string + example: 0000-0002-1825-0097 + name_identifier_scheme: + type: string + example: ORCID + enum: + - ORCID + - ROR + - ISNI + - GRID + name_identifier_scheme_uri: + type: string + example: 'https://orcid.org/' + affiliation_identifier: + type: string + example: 'https://ror.org/05gq02987' + affiliation_identifier_scheme: + type: string + example: ROR + enum: + - ROR + - GRID + - ISNI + affiliation_identifier_scheme_uri: + type: string + example: 'https://ror.org/' IdentifierDto: required: - creators @@ -6887,9 +6684,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: b97cd56b-66ca-4354-9e6c-f47210cfaaec type: type: string example: database @@ -7129,21 +6926,17 @@ components: - draft - published database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid query_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid view_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid query_normalized: type: string example: >- @@ -7182,9 +6975,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 39693413-e0ce-46da-ad5e-029c0556d439 funder_name: type: string example: European Commission @@ -7218,9 +7011,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: ce9d11f0-60a2-448d-a3e4-44719a443e8a value: type: string example: 10.70124/dc4zh-9ce78 @@ -7319,9 +7112,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 787439d0-e85e-400c-a7e6-996a023bfad9 name: type: string example: Air Quality @@ -7329,9 +7122,9 @@ components: type: string example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 2b5b2b03-fdd0-40d6-afe0-e5d02fd839e4 internal_name: type: string example: air_quality @@ -7382,9 +7175,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: 41ed10e0-687b-4e18-8521-810f5cffbce1 name: type: string example: Air Quality @@ -7392,9 +7185,9 @@ components: type: string example: Air Quality in Austria database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: a8fec026-dfaf-4b1d-8f6c-f01720d91705 internal_name: type: string example: air_quality @@ -7431,9 +7224,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: a453e444-e00d-41ca-902c-11e9c54b39f1 name: maxLength: 64 minLength: 0 @@ -7467,26 +7260,20 @@ components: example: Column comment enums: type: array - example: - - val1 items: - type: string - example: '["val1"]' + $ref: '#/components/schemas/EnumDto' sets: type: array - example: - - val1 items: - type: string - example: '["val1"]' + $ref: '#/components/schemas/SetDto' database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 911f9052-c58c-4e1c-b3f2-66af2107be16 table_id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: bfffa915-a547-4466-9c65-ddc0d38fdb08 ord: type: integer format: int32 @@ -7569,9 +7356,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 23 + type: string + format: uuid + example: 8cabc011-4bdf-44d4-9d33-b2648e2ddbf1 uri: type: string example: 'http://www.wikidata.org/entity/Q202444' @@ -7580,9 +7367,35 @@ components: example: given name description: type: string - example: >- - name typically used to differentiate people from the same family, - clan, or other social group who have a common last name + example: >- + name typically used to differentiate people from the same family, + clan, or other social group who have a common last name + EnumDto: + required: + - id + - value + type: object + properties: + id: + type: string + format: uuid + example: 5343bb3d-14d3-4eb7-a86f-b8fc553cb315 + value: + type: string + example: '3' + SetDto: + required: + - id + - value + type: object + properties: + id: + type: string + format: uuid + example: 7eb4eded-bacc-4a91-84db-a9ae6ddafda7 + value: + type: string + example: '3' UnitBriefDto: required: - id @@ -7590,9 +7403,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 34 + type: string + format: uuid + example: ba1935e8-6817-488f-af0a-f54389af9000 uri: type: string example: 'http://www.wikidata.org/entity/Q1422583' @@ -7627,33 +7440,6 @@ components: - read - write_own - write_all - CreateUserDto: - required: - - email - - password - - username - type: object - properties: - username: - pattern: '^[a-z0-9]{3,}$' - type: string - example: user - email: - type: string - example: user@example.com - password: - type: string - LoginRequestDto: - required: - - password - - username - type: object - properties: - username: - type: string - example: user - password: - type: string OntologyCreateDto: required: - prefix @@ -7964,18 +7750,18 @@ components: items: $ref: '#/components/schemas/SaveIdentifierCreatorDto' database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: d002e8d5-8db4-4ff7-ab3a-bc3f52d9ec44 query_id: - type: integer - format: int64 + type: string + format: uuid view_id: - type: integer - format: int64 + type: string + format: uuid table_id: - type: integer - format: int64 + type: string + format: uuid publication_day: type: integer format: int32 @@ -8004,9 +7790,9 @@ components: type: string example: Air Quality container_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 0888e108-d521-46e2-9d3e-82099185305b is_public: type: boolean example: true @@ -8027,8 +7813,7 @@ components: type: string example: Air Quality query: - type: string - example: SELECT `id` FROM `air_quality` + $ref: '#/components/schemas/SubsetDto' is_public: type: boolean example: true @@ -8044,16 +7829,24 @@ components: properties: columns: type: array + example: + - id items: type: string + example: '["id"]' referenced_table: type: string + example: sensor referenced_columns: type: array + example: + - other_id items: type: string + example: '["other_id"]' on_update: type: string + example: cascade enum: - restrict - cascade @@ -8062,6 +7855,7 @@ components: - set_default on_delete: type: string + example: cascade enum: - restrict - cascade @@ -8080,7 +7874,7 @@ components: example: Date type: type: string - example: string + example: varchar enum: - char - varchar @@ -8233,10 +8027,10 @@ components: format: int64 example: 50 image_id: - type: integer + type: string description: Image ID - format: int64 - example: 1 + format: uuid + example: 2360f3c4-85e0-4fac-a7c6-73b296b9dde2 ui_host: type: string example: example.com @@ -8259,23 +8053,15 @@ components: - image - internal_name - name - - quota type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 7ddb7e87-b965-43a2-9a24-4fa406d998f4 name: type: string example: Air Quality - host: - type: string - example: data-db - port: - type: integer - format: int32 - example: 3306 image: $ref: '#/components/schemas/ImageDto' quota: @@ -8298,13 +8084,6 @@ components: internal_name: type: string example: air_quality - ui_host: - type: string - example: example.com - ui_port: - type: integer - format: int32 - example: 3306 ColumnBriefDto: required: - database_id @@ -8316,9 +8095,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: a453e444-e00d-41ca-902c-11e9c54b39f1 name: maxLength: 64 minLength: 0 @@ -8328,13 +8107,13 @@ components: type: string example: firstname database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: 911f9052-c58c-4e1c-b3f2-66af2107be16 table_id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: bfffa915-a547-4466-9c65-ddc0d38fdb08 internal_name: maxLength: 64 minLength: 0 @@ -8382,8 +8161,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: ba1935e8-6817-488f-af0a-f54389af9000 uri: type: string name: @@ -8404,8 +8184,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: 7c491e40-082a-47b8-b82c-51d03c520466 uri: type: string example: 'http://www.wikidata.org/' @@ -8465,10 +8246,12 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: ae3f795b-a3da-4ebe-bdc4-21a8ce631e6f type: type: string + example: WARNING enum: - error - warning @@ -8494,24 +8277,20 @@ components: required: - default - id - - jdbc_method - name - version type: object properties: id: - type: integer - format: int64 - example: 5 + type: string + format: uuid + example: 816f55d5-1098-4f60-a4af-c8121c04dcce name: type: string example: mariadb version: type: string example: '10.5' - jdbc_method: - type: string - example: mariadb default: type: boolean example: false @@ -8577,6 +8356,153 @@ components: type: string '@type': type: string + ViewColumnDto: + required: + - database_id + - id + - internal_name + - is_null_allowed + - name + - ord + - type + type: object + properties: + id: + type: string + format: uuid + example: 6aec3a91-2e0b-4e92-a16a-9c3c5e892da1 + name: + maxLength: 64 + minLength: 0 + type: string + example: Given Name + size: + type: integer + format: int64 + example: 255 + d: + type: integer + format: int64 + example: 0 + description: + maxLength: 2048 + minLength: 0 + type: string + example: Column comment + database_id: + type: string + format: uuid + example: 2b5b2b03-fdd0-40d6-afe0-e5d02fd839e4 + ord: + type: integer + format: int32 + example: 0 + internal_name: + maxLength: 64 + minLength: 0 + type: string + example: given_name + index_length: + type: integer + format: int64 + example: 255 + length: + type: integer + format: int64 + example: 255 + type: + type: string + example: varchar + enum: + - char + - varchar + - binary + - varbinary + - tinyblob + - tinytext + - text + - blob + - mediumtext + - mediumblob + - longtext + - longblob + - enum + - set + - serial + - bit + - tinyint + - bool + - smallint + - mediumint + - int + - bigint + - float + - double + - decimal + - date + - datetime + - timestamp + - time + - year + is_null_allowed: + type: boolean + example: false + ViewDto: + required: + - columns + - database_id + - id + - identifiers + - internal_name + - name + - owner + - query + - query_hash + type: object + properties: + id: + type: string + format: uuid + example: 787439d0-e85e-400c-a7e6-996a023bfad9 + name: + type: string + example: Air Quality + identifiers: + type: array + items: + $ref: '#/components/schemas/IdentifierDto' + query: + type: string + example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC + owner: + $ref: '#/components/schemas/UserBriefDto' + columns: + type: array + items: + $ref: '#/components/schemas/ViewColumnDto' + last_retrieved: + type: string + format: date-time + database_id: + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc + internal_name: + type: string + example: air_quality + is_public: + type: boolean + example: true + is_schema_public: + type: boolean + example: true + initial_view: + type: boolean + description: True if it is the default view for the database + example: true + query_hash: + type: string + example: 7de03e818900b6ea6d58ad0306d4a741d658c6df3d1964e89ed2395d8c7e7916 ConstraintsDto: type: object properties: @@ -8601,86 +8527,13 @@ components: type: array items: $ref: '#/components/schemas/PrimaryKeyDto' - DatabaseDto: - required: - - accesses - - contact - - exchange_name - - id - - identifiers - - internal_name - - is_public - - is_schema_public - - name - - owner - - subsets - - tables - - views - type: object - properties: - id: - type: integer - format: int64 - example: 3 - name: - type: string - example: Air Quality - description: - type: string - example: Air Quality - tables: - type: array - items: - $ref: '#/components/schemas/TableDto' - views: - type: array - items: - $ref: '#/components/schemas/ViewDto' - container: - $ref: '#/components/schemas/ContainerDto' - accesses: - type: array - items: - $ref: '#/components/schemas/DatabaseAccessDto' - identifiers: - type: array - items: - $ref: '#/components/schemas/IdentifierDto' - subsets: - type: array - items: - $ref: '#/components/schemas/IdentifierDto' - contact: - $ref: '#/components/schemas/UserBriefDto' - owner: - $ref: '#/components/schemas/UserBriefDto' - last_retrieved: - type: string - format: date-time - exchange_name: - type: string - example: dbrepo - exchange_type: - type: string - example: topic - internal_name: - type: string - example: air_quality - is_public: - type: boolean - example: true - is_schema_public: - type: boolean - example: true - preview_image: - type: string ForeignKeyBriefDto: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a ForeignKeyDto: required: - name @@ -8690,9 +8543,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a name: type: string example: fk_name @@ -8730,9 +8583,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: f2b740ec-0b13-4d07-88a9-529d354bba6a column: $ref: '#/components/schemas/ColumnBriefDto' foreign_key: @@ -8746,9 +8599,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 8 + type: string + format: uuid + example: d984f9d7-e8a7-4b81-b59a-862db1871f18 table: $ref: '#/components/schemas/TableBriefDto' column: @@ -8770,9 +8623,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 3 + type: string + format: uuid + example: d346f844-b84c-490f-9aec-725a2dc8f820 name: type: string example: Air Quality @@ -8794,17 +8647,15 @@ components: type: array items: $ref: '#/components/schemas/ColumnDto' - database: - $ref: '#/components/schemas/DatabaseDto' constraints: $ref: '#/components/schemas/ConstraintsDto' last_retrieved: type: string format: date-time database_id: - type: integer - format: int64 - example: 2 + type: string + format: uuid + example: fc29f89c-86a8-4020-9e36-4d954736c6cc internal_name: type: string example: air_quality @@ -8854,9 +8705,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 5 + type: string + format: uuid + example: d984f9d7-e8a7-4b81-b59a-862db1871f13 name: type: string example: uk_name @@ -8866,155 +8717,6 @@ components: type: array items: $ref: '#/components/schemas/ColumnBriefDto' - ViewColumnDto: - required: - - database_id - - id - - internal_name - - is_null_allowed - - name - - ord - - type - type: object - properties: - id: - type: integer - format: int64 - example: 12 - name: - maxLength: 64 - minLength: 0 - type: string - example: Given Name - size: - type: integer - format: int64 - example: 255 - d: - type: integer - format: int64 - example: 0 - description: - maxLength: 2048 - minLength: 0 - type: string - example: Column comment - database_id: - type: integer - format: int64 - example: 1 - ord: - type: integer - format: int32 - example: 0 - internal_name: - maxLength: 64 - minLength: 0 - type: string - example: given_name - index_length: - type: integer - format: int64 - example: 255 - length: - type: integer - format: int64 - example: 255 - type: - type: string - example: varchar - enum: - - char - - varchar - - binary - - varbinary - - tinyblob - - tinytext - - text - - blob - - mediumtext - - mediumblob - - longtext - - longblob - - enum - - set - - serial - - bit - - tinyint - - bool - - smallint - - mediumint - - int - - bigint - - float - - double - - decimal - - date - - datetime - - timestamp - - time - - year - is_null_allowed: - type: boolean - example: false - ViewDto: - required: - - columns - - database_id - - id - - identifiers - - internal_name - - name - - owner - - query - - query_hash - type: object - properties: - id: - type: integer - format: int64 - example: 4 - name: - type: string - example: Air Quality - identifiers: - type: array - items: - $ref: '#/components/schemas/IdentifierDto' - query: - type: string - example: SELECT `id` FROM `air_quality` ORDER BY `value` DESC - database: - $ref: '#/components/schemas/DatabaseDto' - owner: - $ref: '#/components/schemas/UserBriefDto' - columns: - type: array - items: - $ref: '#/components/schemas/ViewColumnDto' - last_retrieved: - type: string - format: date-time - database_id: - type: integer - format: int64 - example: 1 - internal_name: - type: string - example: air_quality - is_public: - type: boolean - example: true - is_schema_public: - type: boolean - example: true - initial_view: - type: boolean - description: True if it is the default view for the database - example: true - query_hash: - type: string - example: 7de03e818900b6ea6d58ad0306d4a741d658c6df3d1964e89ed2395d8c7e7916 TableColumnEntityDto: required: - column_id @@ -9033,17 +8735,17 @@ components: type: string example: open source semantic web framework for Java database_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 475b4107-a64d-4495-a7ef-3cb0dadd4804 table_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 9a9208af-90ea-4382-9a11-0c8f6d89bd1f column_id: - type: integer - format: int64 - example: 1 + type: string + format: uuid + example: 297860e3-3b29-451c-ae8a-a85ed5941018 ContainerBriefDto: required: - count @@ -9056,9 +8758,9 @@ components: type: object properties: id: - type: integer - format: int64 - example: 4 + type: string + format: uuid + example: 7ddb7e87-b965-43a2-9a24-4fa406d998f4 hash: type: string example: f829dd8a884182d0da846f365dee1221fd16610a14c81b8f9f295ff162749e50 @@ -9086,8 +8788,9 @@ components: type: object properties: id: - type: integer - format: int64 + type: string + format: uuid + example: 8cabc011-4bdf-44d4-9d33-b2648e2ddbf1 uri: type: string name: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3fea2c60f0b9d591f5a89736eaaafbc051810b7d..f61bd139cdddfa811d60282d81dc2209fdada312 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -285,13 +285,6 @@ test-data-service: junit: ./dbrepo-data-service/rest-service/target/surefire-reports/TEST-*.xml coverage: '/Total.*?([0-9]{1,3})%/' -test-upload-service: - image: maven:3-openjdk-${JAVA_VERSION} - stage: test - script: - - "mvn -f ./dbrepo-metadata-service/pom.xml clean install $MAVEN_OPTS -DskipTests" - - "mvn -f ./dbrepo-upload-service/pom.xml clean test $MAVEN_OPTS" - test-analyse-service: image: docker.io/python:${PYTHON_VERSION}-alpine${ALPINE_VERSION} stage: test diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock index d600643542c4764ae750491e59e0fd8382a1ace7..9e59a2fef8b9ff3d5c28749b242c8c9c331936d3 100644 --- a/dbrepo-analyse-service/Pipfile.lock +++ b/dbrepo-analyse-service/Pipfile.lock @@ -26,90 +26,90 @@ }, "aiohttp": { "hashes": [ - "sha256:0450ada317a65383b7cce9576096150fdb97396dcfe559109b403c7242faffef", - "sha256:0b5263dcede17b6b0c41ef0c3ccce847d82a7da98709e75cf7efde3e9e3b5cae", - "sha256:0d5176f310a7fe6f65608213cc74f4228e4f4ce9fd10bcb2bb6da8fc66991462", - "sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a", - "sha256:145a73850926018ec1681e734cedcf2716d6a8697d90da11284043b745c286d5", - "sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0", - "sha256:246067ba0cf5560cf42e775069c5d80a8989d14a7ded21af529a4e10e3e0f0e6", - "sha256:2c311e2f63e42c1bf86361d11e2c4a59f25d9e7aabdbdf53dc38b885c5435cdb", - "sha256:2cee3b117a8d13ab98b38d5b6bdcd040cfb4181068d05ce0c474ec9db5f3c5bb", - "sha256:2de1378f72def7dfb5dbd73d86c19eda0ea7b0a6873910cc37d57e80f10d64e1", - "sha256:30f546358dfa0953db92ba620101fefc81574f87b2346556b90b5f3ef16e55ce", - "sha256:34245498eeb9ae54c687a07ad7f160053911b5745e186afe2d0c0f2898a1ab8a", - "sha256:392432a2dde22b86f70dd4a0e9671a349446c93965f261dbaecfaf28813e5c42", - "sha256:3c0600bcc1adfaaac321422d615939ef300df81e165f6522ad096b73439c0f58", - "sha256:4016e383f91f2814e48ed61e6bda7d24c4d7f2402c75dd28f7e1027ae44ea204", - "sha256:40cd36749a1035c34ba8d8aaf221b91ca3d111532e5ccb5fa8c3703ab1b967ed", - "sha256:413ad794dccb19453e2b97c2375f2ca3cdf34dc50d18cc2693bd5aed7d16f4b9", - "sha256:4a93d28ed4b4b39e6f46fd240896c29b686b75e39cc6992692e3922ff6982b4c", - "sha256:4ee84c2a22a809c4f868153b178fe59e71423e1f3d6a8cd416134bb231fbf6d3", - "sha256:50c5c7b8aa5443304c55c262c5693b108c35a3b61ef961f1e782dd52a2f559c7", - "sha256:525410e0790aab036492eeea913858989c4cb070ff373ec3bc322d700bdf47c1", - "sha256:526c900397f3bbc2db9cb360ce9c35134c908961cdd0ac25b1ae6ffcaa2507ff", - "sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802", - "sha256:584096938a001378484aa4ee54e05dc79c7b9dd933e271c744a97b3b6f644957", - "sha256:6130459189e61baac5a88c10019b21e1f0c6d00ebc770e9ce269475650ff7f73", - "sha256:67453e603cea8e85ed566b2700efa1f6916aefbc0c9fcb2e86aaffc08ec38e78", - "sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef", - "sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e", - "sha256:74bd573dde27e58c760d9ca8615c41a57e719bff315c9adb6f2a4281a28e8798", - "sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0", - "sha256:76719dd521c20a58a6c256d058547b3a9595d1d885b830013366e27011ffe804", - "sha256:7c3623053b85b4296cd3925eeb725e386644fd5bc67250b3bb08b0f144803e7b", - "sha256:7e44eba534381dd2687be50cbd5f2daded21575242ecfdaf86bbeecbc38dae8e", - "sha256:7fe3d65279bfbee8de0fb4f8c17fc4e893eed2dba21b2f680e930cc2b09075c5", - "sha256:8340def6737118f5429a5df4e88f440746b791f8f1c4ce4ad8a595f42c980bd5", - "sha256:84ede78acde96ca57f6cf8ccb8a13fbaf569f6011b9a52f870c662d4dc8cd854", - "sha256:850ff6155371fd802a280f8d369d4e15d69434651b844bde566ce97ee2277420", - "sha256:87a2e00bf17da098d90d4145375f1d985a81605267e7f9377ff94e55c5d769eb", - "sha256:88d385b8e7f3a870146bf5ea31786ef7463e99eb59e31db56e2315535d811f55", - "sha256:8a2fb742ef378284a50766e985804bd6adb5adb5aa781100b09befdbfa757b65", - "sha256:8dc0fba9a74b471c45ca1a3cb6e6913ebfae416678d90529d188886278e7f3f6", - "sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1", - "sha256:8fd12d0f989c6099e7b0f30dc6e0d1e05499f3337461f0b2b0dadea6c64b89df", - "sha256:9060addfa4ff753b09392efe41e6af06ea5dd257829199747b9f15bfad819460", - "sha256:930ffa1925393381e1e0a9b82137fa7b34c92a019b521cf9f41263976666a0d6", - "sha256:936d8a4f0f7081327014742cd51d320296b56aa6d324461a13724ab05f4b2933", - "sha256:97fe431f2ed646a3b56142fc81d238abcbaff08548d6912acb0b19a0cadc146b", - "sha256:9bd8695be2c80b665ae3f05cb584093a1e59c35ecb7d794d1edd96e8cc9201d7", - "sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259", - "sha256:a478aa11b328983c4444dacb947d4513cb371cd323f3845e53caeda6be5589d5", - "sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0", - "sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9", - "sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9", - "sha256:a7442662afebbf7b4c6d28cb7aab9e9ce3a5df055fc4116cc7228192ad6cb484", - "sha256:aa8a8caca81c0a3e765f19c6953416c58e2f4cc1b84829af01dd1c771bb2f91f", - "sha256:ab3247d58b393bda5b1c8f31c9edece7162fc13265334217785518dd770792b8", - "sha256:b10a47e5390c4b30a0d58ee12581003be52eedd506862ab7f97da7a66805befb", - "sha256:b34508f1cd928ce915ed09682d11307ba4b37d0708d1f28e5774c07a7674cac9", - "sha256:b8d3bb96c147b39c02d3db086899679f31958c5d81c494ef0fc9ef5bb1359b3d", - "sha256:b9d45dbb3aaec05cf01525ee1a7ac72de46a8c425cb75c003acd29f76b1ffe94", - "sha256:bf4480a5438f80e0f1539e15a7eb8b5f97a26fe087e9828e2c0ec2be119a9f72", - "sha256:c160a04283c8c6f55b5bf6d4cad59bb9c5b9c9cd08903841b25f1f7109ef1259", - "sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f", - "sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9", - "sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df", - "sha256:ce1bb21fc7d753b5f8a5d5a4bae99566386b15e716ebdb410154c16c91494d7f", - "sha256:d1c031a7572f62f66f1257db37ddab4cb98bfaf9b9434a3b4840bf3560f5e788", - "sha256:d589264dbba3b16e8951b6f145d1e6b883094075283dafcab4cdd564a9e353a0", - "sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c", - "sha256:e10c440d142fa8b32cfdb194caf60ceeceb3e49807072e0dc3a8887ea80e8c16", - "sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d", - "sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250", - "sha256:e4cecdb52aaa9994fbed6b81d4568427b6002f0a91c322697a4bfcc2b2363f5a", - "sha256:e5148ca8955affdfeb864aca158ecae11030e952b25b3ae15d4e2b5ba299bad2", - "sha256:e6b2732ef3bafc759f653a98881b5b9cdef0716d98f013d376ee8dfd7285abf1", - "sha256:ea756b5a7bac046d202a9a3889b9a92219f885481d78cd318db85b15cc0b7bcf", - "sha256:edb69b9589324bdc40961cdf0657815df674f1743a8d5ad9ab56a99e4833cfdd", - "sha256:f0203433121484b32646a5f5ea93ae86f3d9559d7243f07e8c0eab5ff8e3f70e", - "sha256:f6a19bcab7fbd8f8649d6595624856635159a6527861b9cdc3447af288a00c00", - "sha256:f752e80606b132140883bb262a457c475d219d7163d996dc9072434ffb0784c4", - "sha256:f7914ab70d2ee8ab91c13e5402122edbc77821c66d2758abb53aabe87f013287" + "sha256:00c8ac69e259c60976aa2edae3f13d9991cf079aaa4d3cd5a49168ae3748dee3", + "sha256:01816f07c9cc9d80f858615b1365f8319d6a5fd079cd668cc58e15aafbc76a54", + "sha256:02876bf2f69b062584965507b07bc06903c2dc93c57a554b64e012d636952654", + "sha256:0e9eb7e5764abcb49f0e2bd8f5731849b8728efbf26d0cac8e81384c95acec3f", + "sha256:0f6b2c5b4a4d22b8fb2c92ac98e0747f5f195e8e9448bfb7404cd77e7bfa243f", + "sha256:1982c98ac62c132d2b773d50e2fcc941eb0b8bad3ec078ce7e7877c4d5a2dce7", + "sha256:1e83fb1991e9d8982b3b36aea1e7ad27ea0ce18c14d054c7a404d68b0319eebb", + "sha256:25de43bb3cf83ad83efc8295af7310219af6dbe4c543c2e74988d8e9c8a2a917", + "sha256:28a772757c9067e2aee8a6b2b425d0efaa628c264d6416d283694c3d86da7689", + "sha256:2a4a13dfbb23977a51853b419141cd0a9b9573ab8d3a1455c6e63561387b52ff", + "sha256:2a8a6bc19818ac3e5596310ace5aa50d918e1ebdcc204dc96e2f4d505d51740c", + "sha256:2eabb269dc3852537d57589b36d7f7362e57d1ece308842ef44d9830d2dc3c90", + "sha256:35cda4e07f5e058a723436c4d2b7ba2124ab4e0aa49e6325aed5896507a8a42e", + "sha256:42d689a5c0a0c357018993e471893e939f555e302313d5c61dfc566c2cad6185", + "sha256:4586a68730bd2f2b04a83e83f79d271d8ed13763f64b75920f18a3a677b9a7f0", + "sha256:47dc018b1b220c48089b5b9382fbab94db35bef2fa192995be22cbad3c5730c8", + "sha256:507ab05d90586dacb4f26a001c3abf912eb719d05635cbfad930bdbeb469b36c", + "sha256:5194143927e494616e335d074e77a5dac7cd353a04755330c9adc984ac5a628e", + "sha256:51c3ff9c7a25f3cad5c09d9aacbc5aefb9267167c4652c1eb737989b554fe278", + "sha256:55789e93c5ed71832e7fac868167276beadf9877b85697020c46e9a75471f55f", + "sha256:5724cc77f4e648362ebbb49bdecb9e2b86d9b172c68a295263fa072e679ee69d", + "sha256:5ad8f1c19fe277eeb8bc45741c6d60ddd11d705c12a4d8ee17546acff98e0802", + "sha256:5ceb81a4db2decdfa087381b5fc5847aa448244f973e5da232610304e199e7b2", + "sha256:64815c6f02e8506b10113ddbc6b196f58dbef135751cc7c32136df27b736db09", + "sha256:66047eacbc73e6fe2462b77ce39fc170ab51235caf331e735eae91c95e6a11e4", + "sha256:669dd33f028e54fe4c96576f406ebb242ba534dd3a981ce009961bf49960f117", + "sha256:684eea71ab6e8ade86b9021bb62af4bf0881f6be4e926b6b5455de74e420783a", + "sha256:6b35aab22419ba45f8fc290d0010898de7a6ad131e468ffa3922b1b0b24e9d2e", + "sha256:7104d5b3943c6351d1ad7027d90bdd0ea002903e9f610735ac99df3b81f102ee", + "sha256:718d5deb678bc4b9d575bfe83a59270861417da071ab44542d0fcb6faa686636", + "sha256:747ec46290107a490d21fe1ff4183bef8022b848cf9516970cb31de6d9460088", + "sha256:7836587eef675a17d835ec3d98a8c9acdbeb2c1d72b0556f0edf4e855a25e9c1", + "sha256:78e4dd9c34ec7b8b121854eb5342bac8b02aa03075ae8618b6210a06bbb8a115", + "sha256:7b77ee42addbb1c36d35aca55e8cc6d0958f8419e458bb70888d8c69a4ca833d", + "sha256:7c1b20a1ace54af7db1f95af85da530fe97407d9063b7aaf9ce6a32f44730778", + "sha256:7f27eec42f6c3c1df09cfc1f6786308f8b525b8efaaf6d6bd76c1f52c6511f6a", + "sha256:82c249f2bfa5ecbe4a1a7902c81c0fba52ed9ebd0176ab3047395d02ad96cfcb", + "sha256:85fa0b18558eb1427090912bd456a01f71edab0872f4e0f9e4285571941e4090", + "sha256:89ce611b1eac93ce2ade68f1470889e0173d606de20c85a012bfa24be96cf867", + "sha256:8ce789231404ca8fff7f693cdce398abf6d90fd5dae2b1847477196c243b1fbb", + "sha256:90d571c98d19a8b6e793b34aa4df4cee1e8fe2862d65cc49185a3a3d0a1a3996", + "sha256:9229d8613bd8401182868fe95688f7581673e1c18ff78855671a4b8284f47bcb", + "sha256:93a1f7d857c4fcf7cabb1178058182c789b30d85de379e04f64c15b7e88d66fb", + "sha256:967b93f21b426f23ca37329230d5bd122f25516ae2f24a9cea95a30023ff8283", + "sha256:9840be675de208d1f68f84d578eaa4d1a36eee70b16ae31ab933520c49ba1325", + "sha256:9862d077b9ffa015dbe3ce6c081bdf35135948cb89116e26667dd183550833d1", + "sha256:9b5b37c863ad5b0892cc7a4ceb1e435e5e6acd3f2f8d3e11fa56f08d3c67b820", + "sha256:9e64ca2dbea28807f8484c13f684a2f761e69ba2640ec49dacd342763cc265ef", + "sha256:9fe4eb0e7f50cdb99b26250d9328faef30b1175a5dbcfd6d0578d18456bac567", + "sha256:a01fe9f1e05025eacdd97590895e2737b9f851d0eb2e017ae9574d9a4f0b6252", + "sha256:a08ad95fcbd595803e0c4280671d808eb170a64ca3f2980dd38e7a72ed8d1fea", + "sha256:a4fe27dbbeec445e6e1291e61d61eb212ee9fed6e47998b27de71d70d3e8777d", + "sha256:a7d474c5c1f0b9405c1565fafdc4429fa7d986ccbec7ce55bc6a330f36409cad", + "sha256:a86dc177eb4c286c19d1823ac296299f59ed8106c9536d2b559f65836e0fb2c6", + "sha256:aa36c35e94ecdb478246dd60db12aba57cfcd0abcad43c927a8876f25734d496", + "sha256:ab915a57c65f7a29353c8014ac4be685c8e4a19e792a79fe133a8e101111438e", + "sha256:af55314407714fe77a68a9ccaab90fdb5deb57342585fd4a3a8102b6d4370080", + "sha256:afcb6b275c2d2ba5d8418bf30a9654fa978b4f819c2e8db6311b3525c86fe637", + "sha256:b27961d65639128336b7a7c3f0046dcc62a9443d5ef962e3c84170ac620cec47", + "sha256:b5b95787335c483cd5f29577f42bbe027a412c5431f2f80a749c80d040f7ca9f", + "sha256:b73a2b139782a07658fbf170fe4bcdf70fc597fae5ffe75e5b67674c27434a9f", + "sha256:b88aca5adbf4625e11118df45acac29616b425833c3be7a05ef63a6a4017bfdb", + "sha256:b992778d95b60a21c4d8d4a5f15aaab2bd3c3e16466a72d7f9bfd86e8cea0d4b", + "sha256:ba40b7ae0f81c7029583a338853f6607b6d83a341a3dcde8bed1ea58a3af1df9", + "sha256:baae005092e3f200de02699314ac8933ec20abf998ec0be39448f6605bce93df", + "sha256:c4bea08a6aad9195ac9b1be6b0c7e8a702a9cec57ce6b713698b4a5afa9c2e33", + "sha256:c6070bcf2173a7146bb9e4735b3c62b2accba459a6eae44deea0eb23e0035a23", + "sha256:c929f9a7249a11e4aa5c157091cfad7f49cc6b13f4eecf9b747104befd9f56f2", + "sha256:c97be90d70f7db3aa041d720bfb95f4869d6063fcdf2bb8333764d97e319b7d0", + "sha256:ce10ddfbe26ed5856d6902162f71b8fe08545380570a885b4ab56aecfdcb07f4", + "sha256:cf1f31f83d16ec344136359001c5e871915c6ab685a3d8dee38e2961b4c81730", + "sha256:d2b25b2eeb35707113b2d570cadc7c612a57f1c5d3e7bb2b13870fe284e08fc0", + "sha256:d33851d85537bbf0f6291ddc97926a754c8f041af759e0aa0230fe939168852b", + "sha256:e06cf4852ce8c4442a59bae5a3ea01162b8fcb49ab438d8548b8dc79375dad8a", + "sha256:e271beb2b1dabec5cd84eb488bdabf9758d22ad13471e9c356be07ad139b3012", + "sha256:f55d0f242c2d1fcdf802c8fabcff25a9d85550a4cf3a9cf5f2a6b5742c992839", + "sha256:f81cba651db8795f688c589dd11a4fbb834f2e59bbf9bb50908be36e416dc760", + "sha256:fa1fb1b61881c8405829c50e9cc5c875bfdbf685edf57a76817dfb50643e4a1a", + "sha256:fa48dac27f41b36735c807d1ab093a8386701bbf00eb6b89a0f69d9fa26b3671", + "sha256:fbfef0666ae9e07abfa2c54c212ac18a1f63e13e0760a769f70b5717742f3ece", + "sha256:fe7065e2215e4bba63dc00db9ae654c1ba3950a5fff691475a32f511142fcddb" ], "markers": "python_version >= '3.9'", - "version": "==3.11.12" + "version": "==3.11.13" }, "aiosignal": { "hashes": [ @@ -180,20 +180,20 @@ }, "boto3": { "hashes": [ - "sha256:777ec08a6fe0ad77fa0607b431542c51d2d2e4145fecd512bee9f383ee4184f2", - "sha256:c9055fe6a33f79c43053c06db432092cfcf88f4b4181950f5ca8f2f0cb6abb87" + "sha256:024c37c2f85f4b907f5fc817d0db6fda7fd6ab3c6148ee4ed35fe7cecdf7db0c", + "sha256:1bbf8bbacb3932956b7020d9a2c49d72c64e21bae9397ba6d3aadffab5e192eb" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.36.24" + "version": "==1.37.4" }, "botocore": { "hashes": [ - "sha256:7d35ba92ccbed7aa7e1563b12bb339bde612d5f845c89bfdd79a6db8c26b9f2e", - "sha256:b8b2ad60e6545aaef3a40163793c39555fcfd67fb081a38695018026c4f4db25" + "sha256:7e15cd487617440e9eac3144044b6a2bd833d7f3e2bed6a2865693cc11489cc3", + "sha256:89130998c82d53f875a42646b692da507c9871b580fd1aea0f861bf9da36e41a" ], "markers": "python_version >= '3.8'", - "version": "==1.36.24" + "version": "==1.37.4" }, "certifi": { "hashes": [ @@ -273,7 +273,7 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "charset-normalizer": { @@ -384,44 +384,48 @@ }, "cryptography": { "hashes": [ - "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7", - "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3", - "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183", - "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69", - "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a", - "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62", - "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911", - "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7", - "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a", - "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41", - "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83", - "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12", - "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864", - "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf", - "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c", - "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2", - "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b", - "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0", - "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4", - "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9", - "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008", - "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862", - "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009", - "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7", - "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f", - "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026", - "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f", - "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd", - "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420", - "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14", - "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00" + "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", + "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41", + "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", + "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5", + "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", + "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d", + "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", + "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", + "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", + "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", + "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", + "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", + "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", + "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", + "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", + "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", + "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562", + "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", + "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", + "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", + "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", + "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", + "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", + "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa", + "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb", + "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", + "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", + "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", + "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", + "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", + "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", + "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", + "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", + "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", + "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" ], "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", - "version": "==44.0.1" + "version": "==44.0.2" }, "dbrepo": { "hashes": [ - "sha256:779e7ee84ae91131e16100fee7143013b4c231dcd3990d418d024ff76af271e9" + "sha256:7ba35243c4ead72be2bf2a2d00a3fbbae4a9c7dabb872cca8ed1b1ce77720b5d" ], "path": "./lib/dbrepo-1.7.0.tar.gz" }, @@ -458,11 +462,12 @@ }, "flask-cors": { "hashes": [ - "sha256:5aadb4b950c4e93745034594d9f3ea6591f734bb3662e16e255ffbf5e89c88ef", - "sha256:b9e307d082a9261c100d8fb0ba909eec6a228ed1b60a8315fd85f783d61910bc" + "sha256:6ccb38d16d6b72bbc156c1c3f192bc435bfcc3c2bc864b2df1eb9b2d97b2403c", + "sha256:fa5cb364ead54bbf401a26dbf03030c6b18fb2fcaf70408096a572b409586b0c" ], "index": "pypi", - "version": "==5.0.0" + "markers": "python_version >= '3.9' and python_version < '4.0'", + "version": "==5.0.1" }, "flask-httpauth": { "hashes": [ @@ -1105,91 +1110,107 @@ }, "propcache": { "hashes": [ - "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", - "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", - "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", - "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", - "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", - "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", - "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", - "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", - "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", - "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", - "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", - "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", - "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", - "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", - "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", - "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", - "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae", - "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", - "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", - "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", - "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", - "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", - "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", - "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", - "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", - "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", - "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", - "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", - "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587", - "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097", - "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", - "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", - "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", - "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541", - "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", - "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", - "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", - "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d", - "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", - "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", - "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", - "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf", - "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1", - "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04", - "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", - "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", - "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb", - "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b", - "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", - "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", - "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", - "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4", - "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", - "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e", - "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", - "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", - "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", - "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", - "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", - "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", - "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", - "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", - "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", - "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681", - "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347", - "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", - "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", - "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", - "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", - "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", - "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", - "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", - "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", - "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", - "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", - "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", - "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", - "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16", - "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", - "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", - "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd", - "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212" + "sha256:02df07041e0820cacc8f739510078f2aadcfd3fc57eaeeb16d5ded85c872c89e", + "sha256:03acd9ff19021bd0567582ac88f821b66883e158274183b9e5586f678984f8fe", + "sha256:03c091bb752349402f23ee43bb2bff6bd80ccab7c9df6b88ad4322258d6960fc", + "sha256:07700939b2cbd67bfb3b76a12e1412405d71019df00ca5697ce75e5ef789d829", + "sha256:0c3e893c4464ebd751b44ae76c12c5f5c1e4f6cbd6fbf67e3783cd93ad221863", + "sha256:119e244ab40f70a98c91906d4c1f4c5f2e68bd0b14e7ab0a06922038fae8a20f", + "sha256:11ae6a8a01b8a4dc79093b5d3ca2c8a4436f5ee251a9840d7790dccbd96cb649", + "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6", + "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c", + "sha256:1c8f7d896a16da9455f882870a507567d4f58c53504dc2d4b1e1d386dfe4588a", + "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c", + "sha256:24c04f8fbf60094c531667b8207acbae54146661657a1b1be6d3ca7773b7a545", + "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e", + "sha256:26a67e5c04e3119594d8cfae517f4b9330c395df07ea65eab16f3d559b7068fe", + "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075", + "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57", + "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf", + "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d", + "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc", + "sha256:3b812b3cb6caacd072276ac0492d249f210006c57726b6484a1e1805b3cfeea0", + "sha256:3c6ec957025bf32b15cbc6b67afe233c65b30005e4c55fe5768e4bb518d712f1", + "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64", + "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340", + "sha256:4544699674faf66fb6b4473a1518ae4999c1b614f0b8297b1cef96bac25381db", + "sha256:46ed02532cb66612d42ae5c3929b5e98ae330ea0f3900bc66ec5f4862069519b", + "sha256:49ea05212a529c2caffe411e25a59308b07d6e10bf2505d77da72891f9a05641", + "sha256:4fa0e7c9c3cf7c276d4f6ab9af8adddc127d04e0fcabede315904d2ff76db626", + "sha256:507c5357a8d8b4593b97fb669c50598f4e6cccbbf77e22fa9598aba78292b4d7", + "sha256:549722908de62aa0b47a78b90531c022fa6e139f9166be634f667ff45632cc92", + "sha256:58e6d2a5a7cb3e5f166fd58e71e9a4ff504be9dc61b88167e75f835da5764d07", + "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e", + "sha256:5d62c4f6706bff5d8a52fd51fec6069bef69e7202ed481486c0bc3874912c787", + "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a", + "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810", + "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d", + "sha256:65a37714b8ad9aba5780325228598a5b16c47ba0f8aeb3dc0514701e4413d7c0", + "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b", + "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043", + "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3", + "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7", + "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d", + "sha256:6c929916cbdb540d3407c66f19f73387f43e7c12fa318a66f64ac99da601bcdf", + "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138", + "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c", + "sha256:742840d1d0438eb7ea4280f3347598f507a199a35a08294afdcc560c3739989d", + "sha256:75e872573220d1ee2305b35c9813626e620768248425f58798413e9c39741f46", + "sha256:794c3dd744fad478b6232289c866c25406ecdfc47e294618bdf1697e69bd64a6", + "sha256:7c0fdbdf6983526e269e5a8d53b7ae3622dd6998468821d660d0daf72779aefa", + "sha256:7c5f5290799a3f6539cc5e6f474c3e5c5fbeba74a5e1e5be75587746a940d51e", + "sha256:7c6e7e4f9167fddc438cd653d826f2222222564daed4116a02a184b464d3ef05", + "sha256:7cedd25e5f678f7738da38037435b340694ab34d424938041aa630d8bac42663", + "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f", + "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c", + "sha256:8526b0941ec5a40220fc4dfde76aed58808e2b309c03e9fa8e2260083ef7157f", + "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7", + "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f", + "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7", + "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9", + "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667", + "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86", + "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51", + "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0", + "sha256:9ff4e9ecb6e4b363430edf2c6e50173a63e0820e549918adef70515f87ced19a", + "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c", + "sha256:a2b9bf8c79b660d0ca1ad95e587818c30ccdb11f787657458d6f26a1ea18c568", + "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af", + "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25", + "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5", + "sha256:a94ffc66738da99232ddffcf7910e0f69e2bbe3a0802e54426dbf0714e1c2ffe", + "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf", + "sha256:b0c1a133d42c6fc1f5fbcf5c91331657a1ff822e87989bf4a6e2e39b818d0ee9", + "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf", + "sha256:bb2f144c6d98bb5cbc94adeb0447cfd4c0f991341baa68eee3f3b0c9c0e83767", + "sha256:be90c94570840939fecedf99fa72839aed70b0ced449b415c85e01ae67422c90", + "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c", + "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d", + "sha256:bf4298f366ca7e1ad1d21bbb58300a6985015909964077afd37559084590c929", + "sha256:c441c841e82c5ba7a85ad25986014be8d7849c3cfbdb6004541873505929a74e", + "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32", + "sha256:cd54895e4ae7d32f1e3dd91261df46ee7483a735017dc6f987904f194aa5fd14", + "sha256:d1323cd04d6e92150bcc79d0174ce347ed4b349d748b9358fd2e497b121e03c8", + "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b", + "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc", + "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa", + "sha256:df03cd88f95b1b99052b52b1bb92173229d7a674df0ab06d2b25765ee8404bce", + "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b", + "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e", + "sha256:e560fd75aaf3e5693b91bcaddd8b314f4d57e99aef8a6c6dc692f935cc1e6bbf", + "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9", + "sha256:ecc2920630283e0783c22e2ac94427f8cca29a04cfdf331467d4f661f4072dac", + "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f", + "sha256:ee0bd3a7b2e184e88d25c9baa6a9dc609ba25b76daae942edfb14499ac7ec374", + "sha256:ee25f1ac091def37c4b59d192bbe3a206298feeb89132a470325bf76ad122a1e", + "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d", + "sha256:f47d52fd9b2ac418c4890aad2f6d21a6b96183c98021f0a48497a904199f006e", + "sha256:f857034dc68d5ceb30fb60afb6ff2103087aea10a01b613985610e007053a121", + "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5", + "sha256:fddb8870bdb83456a489ab67c6b3040a8d5a55069aa6f72f9d872235fbc52f54" ], "markers": "python_version >= '3.9'", - "version": "==0.2.1" + "version": "==0.3.0" }, "pycparser": { "hashes": [ @@ -1453,128 +1474,128 @@ }, "rpds-py": { "hashes": [ - "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518", - "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", - "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", - "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5", - "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", - "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543", - "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", - "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", - "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", - "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", - "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", - "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd", - "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b", - "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4", - "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99", - "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", - "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", - "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", - "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1", - "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", - "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f", - "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3", - "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca", - "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d", - "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e", - "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc", - "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea", - "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", - "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b", - "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c", - "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", - "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723", - "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e", - "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", - "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6", - "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83", - "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091", - "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1", - "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", - "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", - "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728", - "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16", - "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", - "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", - "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7", - "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", - "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730", - "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", - "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25", - "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", - "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055", - "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d", - "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", - "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", - "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", - "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", - "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f", - "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd", - "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", - "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", - "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11", - "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333", - "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", - "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", - "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b", - "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", - "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c", - "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9", - "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", - "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", - "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", - "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", - "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9", - "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c", - "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", - "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", - "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", - "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", - "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", - "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", - "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", - "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", - "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", - "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", - "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", - "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", - "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84", - "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3", - "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", - "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520", - "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831", - "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", - "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf", - "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b", - "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2", - "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3", - "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130", - "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b", - "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de", - "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", - "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d", - "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", - "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e" + "sha256:09cd7dbcb673eb60518231e02874df66ec1296c01a4fcd733875755c02014b19", + "sha256:0f3288930b947cbebe767f84cf618d2cbe0b13be476e749da0e6a009f986248c", + "sha256:0fced9fd4a07a1ded1bac7e961ddd9753dd5d8b755ba8e05acba54a21f5f1522", + "sha256:112b8774b0b4ee22368fec42749b94366bd9b536f8f74c3d4175d4395f5cbd31", + "sha256:11dd60b2ffddba85715d8a66bb39b95ddbe389ad2cfcf42c833f1bcde0878eaf", + "sha256:178f8a60fc24511c0eb756af741c476b87b610dba83270fce1e5a430204566a4", + "sha256:1b08027489ba8fedde72ddd233a5ea411b85a6ed78175f40285bd401bde7466d", + "sha256:1bf5be5ba34e19be579ae873da515a2836a2166d8d7ee43be6ff909eda42b72b", + "sha256:1ed7de3c86721b4e83ac440751329ec6a1102229aa18163f84c75b06b525ad7e", + "sha256:1eedaaccc9bb66581d4ae7c50e15856e335e57ef2734dbc5fd8ba3e2a4ab3cb6", + "sha256:243241c95174b5fb7204c04595852fe3943cc41f47aa14c3828bc18cd9d3b2d6", + "sha256:26bb3e8de93443d55e2e748e9fd87deb5f8075ca7bc0502cfc8be8687d69a2ec", + "sha256:271fa2184cf28bdded86bb6217c8e08d3a169fe0bbe9be5e8d96e8476b707122", + "sha256:28358c54fffadf0ae893f6c1050e8f8853e45df22483b7fff2f6ab6152f5d8bf", + "sha256:285019078537949cecd0190f3690a0b0125ff743d6a53dfeb7a4e6787af154f5", + "sha256:2893d778d4671ee627bac4037a075168b2673c57186fb1a57e993465dbd79a93", + "sha256:2a54027554ce9b129fc3d633c92fa33b30de9f08bc61b32c053dc9b537266fed", + "sha256:2c6ae11e6e93728d86aafc51ced98b1658a0080a7dd9417d24bfb955bb09c3c2", + "sha256:2cfa07c346a7ad07019c33fb9a63cf3acb1f5363c33bc73014e20d9fe8b01cdd", + "sha256:35d5631ce0af26318dba0ae0ac941c534453e42f569011585cb323b7774502a5", + "sha256:3614d280bf7aab0d3721b5ce0e73434acb90a2c993121b6e81a1c15c665298ac", + "sha256:3902df19540e9af4cc0c3ae75974c65d2c156b9257e91f5101a51f99136d834c", + "sha256:3aaf141d39f45322e44fc2c742e4b8b4098ead5317e5f884770c8df0c332da70", + "sha256:3d8abf7896a91fb97e7977d1aadfcc2c80415d6dc2f1d0fca5b8d0df247248f3", + "sha256:3e77febf227a1dc3220159355dba68faa13f8dca9335d97504abf428469fb18b", + "sha256:3e9212f52074fc9d72cf242a84063787ab8e21e0950d4d6709886fb62bcb91d5", + "sha256:3ee9d6f0b38efb22ad94c3b68ffebe4c47865cdf4b17f6806d6c674e1feb4246", + "sha256:4233df01a250b3984465faed12ad472f035b7cd5240ea3f7c76b7a7016084495", + "sha256:4263320ed887ed843f85beba67f8b2d1483b5947f2dc73a8b068924558bfeace", + "sha256:4ab923167cfd945abb9b51a407407cf19f5bee35001221f2911dc85ffd35ff4f", + "sha256:4caafd1a22e5eaa3732acb7672a497123354bef79a9d7ceed43387d25025e935", + "sha256:50fb62f8d8364978478b12d5f03bf028c6bc2af04082479299139dc26edf4c64", + "sha256:55ff4151cfd4bc635e51cfb1c59ac9f7196b256b12e3a57deb9e5742e65941ad", + "sha256:5b98b6c953e5c2bda51ab4d5b4f172617d462eebc7f4bfdc7c7e6b423f6da957", + "sha256:5c9ff044eb07c8468594d12602291c635da292308c8c619244e30698e7fc455a", + "sha256:5e9c206a1abc27e0588cf8b7c8246e51f1a16a103734f7750830a1ccb63f557a", + "sha256:5fb89edee2fa237584e532fbf78f0ddd1e49a47c7c8cfa153ab4849dc72a35e6", + "sha256:633462ef7e61d839171bf206551d5ab42b30b71cac8f10a64a662536e057fdef", + "sha256:66f8d2a17e5838dd6fb9be6baaba8e75ae2f5fa6b6b755d597184bfcd3cb0eba", + "sha256:6959bb9928c5c999aba4a3f5a6799d571ddc2c59ff49917ecf55be2bbb4e3722", + "sha256:698a79d295626ee292d1730bc2ef6e70a3ab135b1d79ada8fde3ed0047b65a10", + "sha256:721f9c4011b443b6e84505fc00cc7aadc9d1743f1c988e4c89353e19c4a968ee", + "sha256:72e680c1518733b73c994361e4b06441b92e973ef7d9449feec72e8ee4f713da", + "sha256:75307599f0d25bf6937248e5ac4e3bde5ea72ae6618623b86146ccc7845ed00b", + "sha256:754fba3084b70162a6b91efceee8a3f06b19e43dac3f71841662053c0584209a", + "sha256:759462b2d0aa5a04be5b3e37fb8183615f47014ae6b116e17036b131985cb731", + "sha256:7938c7b0599a05246d704b3f5e01be91a93b411d0d6cc62275f025293b8a11ce", + "sha256:7b77e07233925bd33fc0022b8537774423e4c6680b6436316c5075e79b6384f4", + "sha256:7e5413d2e2d86025e73f05510ad23dad5950ab8417b7fc6beaad99be8077138b", + "sha256:7f3240dcfa14d198dba24b8b9cb3b108c06b68d45b7babd9eefc1038fdf7e707", + "sha256:7f9682a8f71acdf59fd554b82b1c12f517118ee72c0f3944eda461606dfe7eb9", + "sha256:8d67beb6002441faef8251c45e24994de32c4c8686f7356a1f601ad7c466f7c3", + "sha256:9441af1d25aed96901f97ad83d5c3e35e6cd21a25ca5e4916c82d7dd0490a4fa", + "sha256:98b257ae1e83f81fb947a363a274c4eb66640212516becaff7bef09a5dceacaa", + "sha256:9e9f3a3ac919406bc0414bbbd76c6af99253c507150191ea79fab42fdb35982a", + "sha256:a1c66e71ecfd2a4acf0e4bd75e7a3605afa8f9b28a3b497e4ba962719df2be57", + "sha256:a1e17d8dc8e57d8e0fd21f8f0f0a5211b3fa258b2e444c2053471ef93fe25a00", + "sha256:a20cb698c4a59c534c6701b1c24a968ff2768b18ea2991f886bd8985ce17a89f", + "sha256:a970bfaf130c29a679b1d0a6e0f867483cea455ab1535fb427566a475078f27f", + "sha256:a98f510d86f689fcb486dc59e6e363af04151e5260ad1bdddb5625c10f1e95f8", + "sha256:a9d3b728f5a5873d84cba997b9d617c6090ca5721caaa691f3b1a78c60adc057", + "sha256:ad76f44f70aac3a54ceb1813ca630c53415da3a24fd93c570b2dfb4856591017", + "sha256:ae28144c1daa61366205d32abd8c90372790ff79fc60c1a8ad7fd3c8553a600e", + "sha256:b03a8d50b137ee758e4c73638b10747b7c39988eb8e6cd11abb7084266455165", + "sha256:b5a96fcac2f18e5a0a23a75cd27ce2656c66c11c127b0318e508aab436b77428", + "sha256:b5ef909a37e9738d146519657a1aab4584018746a18f71c692f2f22168ece40c", + "sha256:b79f5ced71efd70414a9a80bbbfaa7160da307723166f09b69773153bf17c590", + "sha256:b91cceb5add79ee563bd1f70b30896bd63bc5f78a11c1f00a1e931729ca4f1f4", + "sha256:b92f5654157de1379c509b15acec9d12ecf6e3bc1996571b6cb82a4302060447", + "sha256:c04ca91dda8a61584165825907f5c967ca09e9c65fe8966ee753a3f2b019fe1e", + "sha256:c1f8afa346ccd59e4e5630d5abb67aba6a9812fddf764fd7eb11f382a345f8cc", + "sha256:c5334a71f7dc1160382d45997e29f2637c02f8a26af41073189d79b95d3321f1", + "sha256:c617d7453a80e29d9973b926983b1e700a9377dbe021faa36041c78537d7b08c", + "sha256:c632419c3870507ca20a37c8f8f5352317aca097639e524ad129f58c125c61c6", + "sha256:c6760211eee3a76316cf328f5a8bd695b47b1626d21c8a27fb3b2473a884d597", + "sha256:c698d123ce5d8f2d0cd17f73336615f6a2e3bdcedac07a1291bb4d8e7d82a05a", + "sha256:c76b32eb2ab650a29e423525e84eb197c45504b1c1e6e17b6cc91fcfeb1a4b1d", + "sha256:c8f7e90b948dc9dcfff8003f1ea3af08b29c062f681c05fd798e36daa3f7e3e8", + "sha256:c9e799dac1ffbe7b10c1fd42fe4cd51371a549c6e108249bde9cd1200e8f59b4", + "sha256:cafa48f2133d4daa028473ede7d81cd1b9f9e6925e9e4003ebdf77010ee02f35", + "sha256:ce473a2351c018b06dd8d30d5da8ab5a0831056cc53b2006e2a8028172c37ce5", + "sha256:d31ed4987d72aabdf521eddfb6a72988703c091cfc0064330b9e5f8d6a042ff5", + "sha256:d550d7e9e7d8676b183b37d65b5cd8de13676a738973d330b59dc8312df9c5dc", + "sha256:d6adb81564af0cd428910f83fa7da46ce9ad47c56c0b22b50872bc4515d91966", + "sha256:d6f6512a90bd5cd9030a6237f5346f046c6f0e40af98657568fa45695d4de59d", + "sha256:d7031d493c4465dbc8d40bd6cafefef4bd472b17db0ab94c53e7909ee781b9ef", + "sha256:d9f75a06ecc68f159d5d7603b734e1ff6daa9497a929150f794013aa9f6e3f12", + "sha256:db7707dde9143a67b8812c7e66aeb2d843fe33cc8e374170f4d2c50bd8f2472d", + "sha256:e0397dd0b3955c61ef9b22838144aa4bef6f0796ba5cc8edfc64d468b93798b4", + "sha256:e0df046f2266e8586cf09d00588302a32923eb6386ced0ca5c9deade6af9a149", + "sha256:e14f86b871ea74c3fddc9a40e947d6a5d09def5adc2076ee61fb910a9014fb35", + "sha256:e5963ea87f88bddf7edd59644a35a0feecf75f8985430124c253612d4f7d27ae", + "sha256:e768267cbe051dd8d1c5305ba690bb153204a09bf2e3de3ae530de955f5b5580", + "sha256:e9cb79ecedfc156c0692257ac7ed415243b6c35dd969baa461a6888fc79f2f07", + "sha256:ed6f011bedca8585787e5082cce081bac3d30f54520097b2411351b3574e1219", + "sha256:f3429fb8e15b20961efca8c8b21432623d85db2228cc73fe22756c6637aa39e7", + "sha256:f35eff113ad430b5272bbfc18ba111c66ff525828f24898b4e146eb479a2cdda", + "sha256:f3a6cb95074777f1ecda2ca4fa7717caa9ee6e534f42b7575a8f0d4cb0c24013", + "sha256:f7356a6da0562190558c4fcc14f0281db191cdf4cb96e7604c06acfcee96df15", + "sha256:f88626e3f5e57432e6191cd0c5d6d6b319b635e70b40be2ffba713053e5147dd", + "sha256:fad784a31869747df4ac968a351e070c06ca377549e4ace94775aaa3ab33ee06", + "sha256:fc869af5cba24d45fb0399b0cfdbcefcf6910bf4dee5d74036a57cf5264b3ff4", + "sha256:fee513135b5a58f3bb6d89e48326cd5aa308e4bcdf2f7d59f67c861ada482bf8" ], "markers": "python_version >= '3.9'", - "version": "==0.22.3" + "version": "==0.23.1" }, "s3transfer": { "hashes": [ - "sha256:3b39185cb72f5acc77db1a58b6e25b977f28d20496b6e58d6813d75f464d632f", - "sha256:be6ecb39fadd986ef1701097771f87e4d2f821f27f6071c872143884d2950fbc" + "sha256:ca855bdeb885174b5ffa95b9913622459d4ad8e331fc98eb01e6d5eb6a30655d", + "sha256:edae4977e3a122445660c7c114bba949f9d191bae3b34a096f18a1c8c354527a" ], "markers": "python_version >= '3.8'", - "version": "==0.11.2" + "version": "==0.11.3" }, "setuptools": { "hashes": [ - "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", - "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3" + "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2", + "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f" ], "markers": "python_version >= '3.9'", - "version": "==75.8.0" + "version": "==75.8.2" }, "six": { "hashes": [ @@ -1886,7 +1907,7 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "charset-normalizer": { @@ -2169,12 +2190,12 @@ }, "pytest": { "hashes": [ - "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", - "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.4" + "version": "==8.3.5" }, "python-dateutil": { "hashes": [ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.0-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.7.0-py3-none-any.whl index f75ec9ba7a7a4ad6c2897e38abdae20c815f56c7..385c9e224a31ae8811c03908303ea42fc2374d0a 100644 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.0-py3-none-any.whl and b/dbrepo-analyse-service/lib/dbrepo-1.7.0-py3-none-any.whl differ diff --git a/dbrepo-analyse-service/lib/dbrepo-1.7.0.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.7.0.tar.gz index be1dcfe68165001dbeacd670709955723a01e323..823a773ca48627ae548e2e0448bef1f5a224b3d8 100644 Binary files a/dbrepo-analyse-service/lib/dbrepo-1.7.0.tar.gz and b/dbrepo-analyse-service/lib/dbrepo-1.7.0.tar.gz differ diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar index 7072823dcbcc2d91dab2624b91f1e47fad47dbff..1d72200c19c7b9fb124773e3ffc0249d1b535e2f 100644 Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ diff --git a/dbrepo-data-service/pom.xml b/dbrepo-data-service/pom.xml index 697e9ece1b5e0fda90a8a10ddfcb551736c8f109..35784c7d1f3167925a43cdab5104ab676189c950 100644 --- a/dbrepo-data-service/pom.xml +++ b/dbrepo-data-service/pom.xml @@ -8,6 +8,11 @@ <version>3.3.5</version> </parent> + <organization> + <name>TU Wien</name> + <url>https://www.tuwien.ac.at</url> + </organization> + <groupId>at.tuwien</groupId> <artifactId>dbrepo-data-service</artifactId> <name>dbrepo-data-service</name> @@ -54,14 +59,37 @@ <minio.version>8.5.7</minio.version> <guava.version>33.3.0-jre</guava.version> <spark.version>4.0.0-preview2</spark.version> + <keycloak.version>26.0.4</keycloak.version> <scala.version>2.13</scala.version> <antlr-runtime.version>3.5.2</antlr-runtime.version> <micrometer.version>1.10.0</micrometer.version> <!-- see https://github.com/apache/spark/blob/cde8e4a82e20a363861f451ebd5138efb3194ab8/pom.xml --> <hadoop.version>3.4.0</hadoop.version> <jakarta-servlet.version>5.0.0</jakarta-servlet.version> - <sonar.coverage.jacoco.xmlReportPaths>./report/target/site/jacoco-aggregate/jacoco.xml + <sonar.coverage.jacoco.xmlReportPaths> + ./report/target/site/jacoco-aggregate/jacoco.xml </sonar.coverage.jacoco.xmlReportPaths> + <CodeCacheSize>128m</CodeCacheSize> + <extraJavaTestArgs> + -XX:+IgnoreUnrecognizedVMOptions + --add-modules=jdk.incubator.vector + --add-opens=java.base/java.lang=ALL-UNNAMED + --add-opens=java.base/java.lang.invoke=ALL-UNNAMED + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.io=ALL-UNNAMED + --add-opens=java.base/java.net=ALL-UNNAMED + --add-opens=java.base/java.nio=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + --add-opens=java.base/java.util.concurrent=ALL-UNNAMED + --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED + --add-opens=java.base/jdk.internal.ref=ALL-UNNAMED + --add-opens=java.base/sun.nio.ch=ALL-UNNAMED + --add-opens=java.base/sun.nio.cs=ALL-UNNAMED + --add-opens=java.base/sun.security.action=ALL-UNNAMED + --add-opens=java.base/sun.util.calendar=ALL-UNNAMED + -Djdk.reflect.useDirectMethodHandle=false + -Dio.netty.tryReflectionSetAccessible=true + </extraJavaTestArgs> </properties> <dependencies> @@ -208,6 +236,22 @@ <artifactId>commons-validator</artifactId> <version>${commons-validator.version}</version> </dependency> + <dependency> + <groupId>org.jooq</groupId> + <artifactId>jooq</artifactId> + <version>${jooq.version}</version> + </dependency> + <!-- Authentication --> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-common</artifactId> + <version>${keycloak.version}</version> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-admin-client</artifactId> + <version>${keycloak.version}</version> + </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate6</artifactId> @@ -323,7 +367,26 @@ </execution> </executions> </plugin> + <!-- Surefire runs all Java tests --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <!-- Note config is repeated in scalatest config --> + <configuration> + <argLine>@{argLine} -ea -Xmx4g -Xss4m -XX:MaxMetaspaceSize=2g -XX:ReservedCodeCacheSize=${CodeCacheSize} + ${extraJavaTestArgs} + </argLine> + </configuration> + </plugin> </plugins> </build> + <licenses> + <license> + <name>Apache-2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.html</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java index 84d04971e3bbeb376ea77277cdb52ef279a6954b..ba1a0e76da6d1dda766d64c33b68ab452d509618 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java @@ -6,7 +6,7 @@ import at.tuwien.api.error.ApiErrorDto; import at.tuwien.api.user.UserDto; import at.tuwien.exception.*; import at.tuwien.service.AccessService; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -31,13 +31,13 @@ import java.util.UUID; @RequestMapping(path = "/api/database/{databaseId}/access") public class AccessEndpoint extends RestEndpoint { + private final CacheService cacheService; private final AccessService accessService; - private final CredentialService credentialService; @Autowired - public AccessEndpoint(AccessService accessService, CredentialService credentialService) { + public AccessEndpoint(CacheService cacheService, AccessService accessService) { + this.cacheService = cacheService; this.accessService = accessService; - this.credentialService = credentialService; } @PostMapping("/{userId}") @@ -80,8 +80,8 @@ public class AccessEndpoint extends RestEndpoint { throws NotAllowedException, DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, DatabaseMalformedException, MetadataServiceException { log.debug("endpoint give access to database, databaseId={}, userId={}", databaseId, userId); - final DatabaseDto database = credentialService.getDatabase(databaseId); - final UserDto user = credentialService.getUser(userId); + final DatabaseDto database = cacheService.getDatabase(databaseId); + final UserDto user = cacheService.getUser(userId); if (database.getAccesses().stream().anyMatch(a -> a.getUser().getId().equals(userId))) { log.error("Failed to create access to user with id {}: already has access", userId); throw new NotAllowedException("Failed to create access to user with id " + userId + ": already has access"); @@ -137,8 +137,8 @@ public class AccessEndpoint extends RestEndpoint { DatabaseMalformedException, MetadataServiceException { log.debug("endpoint modify access to database, databaseId={}, userId={}, access.type={}", databaseId, userId, access.getType()); - final DatabaseDto database = credentialService.getDatabase(databaseId); - final UserDto user = credentialService.getUser(userId); + final DatabaseDto database = cacheService.getDatabase(databaseId); + final UserDto user = cacheService.getUser(userId); if (database.getAccesses().stream().noneMatch(a -> a.getHuserid().equals(userId))) { log.error("Failed to update access to user with id {}: no access", userId); throw new NotAllowedException("Failed to update access to user with id " + userId + ": no access"); @@ -153,22 +153,6 @@ public class AccessEndpoint extends RestEndpoint { } } - @PutMapping - @PreAuthorize("hasAuthority('system')") - @Operation(summary = "Invalidate access cache for database", - security = {@SecurityRequirement(name = "basicAuth")}, - hidden = true) - @ApiResponses(value = { - @ApiResponse(responseCode = "202", - description = "Invalidated access cache succeeded") - }) - public ResponseEntity<Void> invalidateAccess(@NotNull @PathVariable("databaseId") UUID databaseId) { - log.debug("endpoint empty access cache for database, databaseId={}", databaseId); - credentialService.invalidateAccess(databaseId); - return ResponseEntity.accepted() - .build(); - } - @DeleteMapping("/{userId}") @PreAuthorize("hasAuthority('system')") @Operation(summary = "Revoke access", @@ -208,8 +192,8 @@ public class AccessEndpoint extends RestEndpoint { DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, DatabaseMalformedException, MetadataServiceException { log.debug("endpoint revoke access to database, databaseId={}, userId={}", databaseId, userId); - final DatabaseDto database = credentialService.getDatabase(databaseId); - final UserDto user = credentialService.getUser(userId); + final DatabaseDto database = cacheService.getDatabase(databaseId); + final UserDto user = cacheService.getUser(userId); if (database.getAccesses().stream().noneMatch(a -> a.getUser().getId().equals(userId))) { log.error("Failed to delete access to user with id {}: no access", userId); throw new NotAllowedException("Failed to delete access to user with id " + userId + ": no access"); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 0d12384dfa8842197d20bb608b87434d30cad1c7..801c6b638f3e1548711aa9d82989a83c62adde46 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -10,7 +10,7 @@ import at.tuwien.api.user.internal.UpdateUserPasswordDto; import at.tuwien.exception.*; import at.tuwien.service.AccessService; import at.tuwien.service.ContainerService; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.DatabaseService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -36,18 +36,18 @@ import java.util.UUID; @RequestMapping(path = "/api/database") public class DatabaseEndpoint extends RestEndpoint { + private final CacheService cacheService; private final AccessService accessService; private final DatabaseService databaseService; private final ContainerService containerService; - private final CredentialService credentialService; @Autowired - public DatabaseEndpoint(AccessService accessService, DatabaseService databaseService, - ContainerService containerService, CredentialService credentialService) { + public DatabaseEndpoint(CacheService cacheService, AccessService accessService, DatabaseService databaseService, + ContainerService containerService) { + this.cacheService = cacheService; this.accessService = accessService; this.databaseService = databaseService; this.containerService = containerService; - this.credentialService = credentialService; } @PostMapping @@ -87,7 +87,7 @@ public class DatabaseEndpoint extends RestEndpoint { DatabaseMalformedException, QueryStoreCreateException, MetadataServiceException { log.debug("endpoint create database, data.containerId={}, data.internalName={}, data.username={}", data.getContainerId(), data.getInternalName(), data.getUsername()); - final ContainerDto container = credentialService.getContainer(data.getContainerId()); + final ContainerDto container = cacheService.getContainer(data.getContainerId()); try { final DatabaseDto database = containerService.createDatabase(container, data); containerService.createQueryStore(container, data.getInternalName()); @@ -135,7 +135,7 @@ public class DatabaseEndpoint extends RestEndpoint { DatabaseMalformedException, MetadataServiceException { log.debug("endpoint update user password in database, databaseId={}, data.username={}", databaseId, data.getUsername()); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { databaseService.update(database, data); return ResponseEntity.status(HttpStatus.ACCEPTED) diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java index 245774726f3725252ddb4d834af6ff2b3171ee25..e64deaa758a2a20100671b4526d7bacd609f3a86 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java @@ -1,13 +1,12 @@ package at.tuwien.endpoints; import at.tuwien.ExportResourceDto; -import at.tuwien.api.database.CreateViewDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewColumnDto; import at.tuwien.api.database.ViewDto; -import at.tuwien.api.database.query.ExecuteStatementDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryPersistDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.api.error.ApiErrorDto; import at.tuwien.exception.*; import at.tuwien.mapper.MariaDbMapper; @@ -50,26 +49,26 @@ import java.util.UUID; @RequestMapping(path = "/api/database/{databaseId}/subset") public class SubsetEndpoint extends RestEndpoint { + private final CacheService cacheService; private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; private final MetadataMapper metadataMapper; private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; - private final CredentialService credentialService; private final EndpointValidator endpointValidator; @Autowired - public SubsetEndpoint(MariaDbMapper mariaDbMapper, SubsetService subsetService, MetadataMapper metadataMapper, - MetricsService metricsService, StorageService storageService, DatabaseService databaseService, - CredentialService credentialService, EndpointValidator endpointValidator) { + public SubsetEndpoint(CacheService cacheService, MariaDbMapper mariaDbMapper, SubsetService subsetService, + MetadataMapper metadataMapper, MetricsService metricsService, StorageService storageService, + DatabaseService databaseService, EndpointValidator endpointValidator) { + this.cacheService = cacheService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; this.metadataMapper = metadataMapper; this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; - this.credentialService = credentialService; this.endpointValidator = endpointValidator; } @@ -106,7 +105,7 @@ public class SubsetEndpoint extends RestEndpoint { throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, QueryNotFoundException, NotAllowedException, MetadataServiceException { log.debug("endpoint find subsets in database, databaseId={}, filterPersisted={}", databaseId, filterPersisted); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); endpointValidator.validateOnlyPrivateSchemaAccess(database, principal); final List<QueryDto> queries; try { @@ -167,7 +166,7 @@ public class SubsetEndpoint extends RestEndpoint { MetadataServiceException, TableNotFoundException, QueryMalformedException, NotAllowedException { log.debug("endpoint find subset in database, databaseId={}, subsetId={}, accept={}, timestamp={}", databaseId, subsetId, accept, timestamp); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); endpointValidator.validateOnlyPrivateSchemaAccess(database, principal); final QueryDto subset; try { @@ -248,7 +247,7 @@ public class SubsetEndpoint extends RestEndpoint { schema = @Schema(implementation = ApiErrorDto.class))}), }) public ResponseEntity<List<Map<String, Object>>> create(@NotNull @PathVariable("databaseId") UUID databaseId, - @Valid @RequestBody ExecuteStatementDto data, + @Valid @RequestBody SubsetDto data, Principal principal, @NotNull HttpServletRequest request, @RequestParam(required = false) Instant timestamp, @@ -258,13 +257,12 @@ public class SubsetEndpoint extends RestEndpoint { QueryNotFoundException, StorageUnavailableException, QueryMalformedException, StorageNotFoundException, QueryStoreInsertException, TableMalformedException, PaginationException, QueryNotSupportedException, NotAllowedException, UserNotFoundException, MetadataServiceException, TableNotFoundException, - ViewMalformedException, ViewNotFoundException { - log.debug("endpoint create subset in database, databaseId={}, data.statement={}, page={}, size={}, " + - "timestamp={}", databaseId, data.getStatement(), page, size, - timestamp); + ViewMalformedException, ViewNotFoundException, ImageNotFoundException { + log.debug("endpoint create subset in database, databaseId={}, page={}, size={}, timestamp={}", databaseId, + page, size, timestamp); /* check */ endpointValidator.validateDataParams(page, size); - endpointValidator.validateForbiddenStatements(data.getStatement()); + endpointValidator.validateSubsetParams(data); /* parameters */ final UUID userId; if (principal != null) { @@ -285,10 +283,10 @@ public class SubsetEndpoint extends RestEndpoint { log.debug("timestamp not set: default to {}", timestamp); } /* create */ - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); endpointValidator.validateOnlyPrivateSchemaAccess(database, principal); try { - final UUID subsetId = subsetService.create(database, data.getStatement(), timestamp, userId); + final UUID subsetId = subsetService.create(database, data, timestamp, userId); return getData(databaseId, subsetId, principal, request, timestamp, page, size); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); @@ -340,19 +338,18 @@ public class SubsetEndpoint extends RestEndpoint { @RequestParam(required = false) Long page, @RequestParam(required = false) Long size) throws PaginationException, DatabaseNotFoundException, RemoteUnavailableException, NotAllowedException, - QueryNotFoundException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException, - UserNotFoundException, MetadataServiceException, TableNotFoundException, ViewNotFoundException, - ViewMalformedException { + QueryNotFoundException, DatabaseUnavailableException, QueryMalformedException, UserNotFoundException, + MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException { log.debug("endpoint get subset data, databaseId={}, subsetId={}, principal.name={} page={}, size={}", databaseId, subsetId, principal != null ? principal.getName() : null, page, size); endpointValidator.validateDataParams(page, size); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); if (!database.getIsPublic()) { if (principal == null) { log.error("Failed to re-execute query: no authentication found"); throw new NotAllowedException("Failed to re-execute query: no authentication found"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } log.trace("visibility for database: is_public={}, is_schema_public={}", database.getIsPublic(), database.getIsSchemaPublic()); /* parameters */ @@ -384,12 +381,7 @@ public class SubsetEndpoint extends RestEndpoint { final Dataset<Row> dataset = subsetService.getData(database, query); metricsService.countSubsetGetData(databaseId, subsetId); final String viewName = metadataMapper.queryDtoToViewName(subset); - databaseService.createView(database, CreateViewDto.builder() - .name(viewName) - .isPublic(false) - .isSchemaPublic(false) - .query(query) - .build()); + databaseService.createView(database, viewName, subset.getQuery()); final ViewDto view = databaseService.inspectView(database, viewName); headers.set("Access-Control-Expose-Headers", "X-Id X-Headers"); headers.set("X-Headers", String.join(",", view.getColumns().stream().map(ViewColumnDto::getInternalName).toList())); @@ -448,8 +440,8 @@ public class SubsetEndpoint extends RestEndpoint { DatabaseUnavailableException, QueryNotFoundException, UserNotFoundException, MetadataServiceException { log.debug("endpoint persist query, databaseId={}, queryId={}, data.persist={}, principal.name={}", databaseId, queryId, data.getPersist(), principal.getName()); - final DatabaseDto database = credentialService.getDatabase(databaseId); - credentialService.getAccess(databaseId, getId(principal)); + final DatabaseDto database = cacheService.getDatabase(databaseId); + cacheService.getAccess(databaseId, getId(principal)); try { subsetService.persist(database, queryId, data.getPersist()); final QueryDto dto = subsetService.findById(database, queryId); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index fc7dd5be7909eb412bdc07df53645d73f0a35c34..ab306ea6081163f17c3b36878b8fee36609b2036 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -49,28 +49,28 @@ import java.util.UUID; @RequestMapping(path = "/api/database/{databaseId}/table") public class TableEndpoint extends RestEndpoint { + private final CacheService cacheService; private final TableService tableService; private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; - private final CredentialService credentialService; private final EndpointValidator endpointValidator; private final MetadataServiceGateway metadataServiceGateway; @Autowired - public TableEndpoint(TableService tableService, MariaDbMapper mariaDbMapper, SubsetService subsetService, - MetricsService metricsService, StorageService storageService, DatabaseService databaseService, - CredentialService credentialService, EndpointValidator endpointValidator, + public TableEndpoint(CacheService cacheService, TableService tableService, MariaDbMapper mariaDbMapper, + SubsetService subsetService, MetricsService metricsService, StorageService storageService, + DatabaseService databaseService, EndpointValidator endpointValidator, MetadataServiceGateway metadataServiceGateway) { + this.cacheService = cacheService; this.tableService = tableService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; - this.credentialService = credentialService; this.endpointValidator = endpointValidator; this.metadataServiceGateway = metadataServiceGateway; } @@ -118,7 +118,7 @@ public class TableEndpoint extends RestEndpoint { throw new TableMalformedException("Table must have a primary key"); } /* create */ - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { final TableDto table = databaseService.createTable(database, data); return ResponseEntity.status(HttpStatus.CREATED) @@ -159,12 +159,14 @@ public class TableEndpoint extends RestEndpoint { public ResponseEntity<TableDto> update(@NotNull @PathVariable("databaseId") UUID databaseId, @NotNull @PathVariable("tableId") UUID tableId, @Valid @RequestBody TableUpdateDto data) throws RemoteUnavailableException, - TableMalformedException, DatabaseUnavailableException, TableNotFoundException, MetadataServiceException { + TableMalformedException, DatabaseUnavailableException, TableNotFoundException, MetadataServiceException, + DatabaseNotFoundException { log.debug("endpoint update table, databaseId={}, data.description={}", databaseId, data.getDescription()); /* create */ - final TableDto table = credentialService.getTable(databaseId, tableId); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.updateTable(table, data); + tableService.updateTable(database, table, data); return ResponseEntity.status(HttpStatus.ACCEPTED) .build(); } catch (SQLException e) { @@ -203,11 +205,12 @@ public class TableEndpoint extends RestEndpoint { public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") UUID databaseId, @NotNull @PathVariable("tableId") UUID tableId) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - QueryMalformedException, MetadataServiceException { + QueryMalformedException, MetadataServiceException, DatabaseNotFoundException { log.debug("endpoint delete table, databaseId={}, tableId={}", databaseId, tableId); - final TableDto table = credentialService.getTable(databaseId, tableId); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.delete(table); + tableService.delete(database, table); return ResponseEntity.status(HttpStatus.ACCEPTED) .build(); } catch (SQLException e) { @@ -275,29 +278,29 @@ public class TableEndpoint extends RestEndpoint { timestamp = Instant.now(); log.debug("timestamp not set: default to {}", timestamp); } - final TableDto table = credentialService.getTable(databaseId, tableId); + final TableDto table = cacheService.getTable(databaseId, tableId); if (!table.getIsPublic()) { if (principal == null) { log.error("Failed find table data: authentication required"); throw new NotAllowedException("Failed to find table data: authentication required"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } + final DatabaseDto database = cacheService.getDatabase(databaseId); try { final HttpHeaders headers = new HttpHeaders(); if (request.getMethod().equals("HEAD")) { headers.set("Access-Control-Expose-Headers", "X-Count"); - headers.set("X-Count", "" + tableService.getCount(table, timestamp)); + headers.set("X-Count", "" + tableService.getCount(database, table, timestamp)); return ResponseEntity.ok() .headers(headers) .build(); } headers.set("Access-Control-Expose-Headers", "X-Headers"); headers.set("X-Headers", String.join(",", table.getColumns().stream().map(ColumnDto::getInternalName).toList())); - final String query = mariaDbMapper.defaultRawSelectQuery(table.getDatabase().getInternalName(), + final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), table.getInternalName(), timestamp, page, size); - final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(table.getTdbid()), - query); + final Dataset<Row> dataset = subsetService.getData(database, query); metricsService.countTableGetData(databaseId, tableId); return ResponseEntity.ok() .headers(headers) @@ -345,13 +348,14 @@ public class TableEndpoint extends RestEndpoint { @RequestHeader("Authorization") String authorization) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, TableMalformedException, QueryMalformedException, NotAllowedException, StorageUnavailableException, - StorageNotFoundException, MetadataServiceException { + StorageNotFoundException, MetadataServiceException, DatabaseNotFoundException { log.debug("endpoint insert raw table data, databaseId={}, tableId={}", databaseId, tableId); - final TableDto table = credentialService.getTable(databaseId, tableId); - final DatabaseAccessDto access = credentialService.getAccess(databaseId, getId(principal)); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseAccessDto access = cacheService.getAccess(databaseId, getId(principal)); endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(access.getType(), table.getOwner().getId(), getId(principal)); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.createTuple(table, data); + tableService.createTuple(database, table, data); metadataServiceGateway.updateTableStatistics(databaseId, tableId, authorization); return ResponseEntity.status(HttpStatus.CREATED) .build(); @@ -397,14 +401,16 @@ public class TableEndpoint extends RestEndpoint { @NotNull Principal principal, @RequestHeader("Authorization") String authorization) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - TableMalformedException, QueryMalformedException, NotAllowedException, MetadataServiceException { + TableMalformedException, QueryMalformedException, NotAllowedException, MetadataServiceException, + DatabaseNotFoundException { log.debug("endpoint update raw table data, databaseId={}, tableId={}, data.keys={}", databaseId, tableId, data.getKeys()); - final TableDto table = credentialService.getTable(databaseId, tableId); - final DatabaseAccessDto access = credentialService.getAccess(databaseId, getId(principal)); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseAccessDto access = cacheService.getAccess(databaseId, getId(principal)); endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(access.getType(), table.getOwner().getId(), getId(principal)); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.updateTuple(table, data); + tableService.updateTuple(database, table, data); metadataServiceGateway.updateTableStatistics(databaseId, tableId, authorization); return ResponseEntity.status(HttpStatus.ACCEPTED) .build(); @@ -450,14 +456,16 @@ public class TableEndpoint extends RestEndpoint { @NotNull Principal principal, @RequestHeader("Authorization") String authorization) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - TableMalformedException, QueryMalformedException, NotAllowedException, MetadataServiceException { + TableMalformedException, QueryMalformedException, NotAllowedException, MetadataServiceException, + DatabaseNotFoundException { log.debug("endpoint delete raw table data, databaseId={}, tableId={}, data.keys={}", databaseId, tableId, data.getKeys()); - final TableDto table = credentialService.getTable(databaseId, tableId); - final DatabaseAccessDto access = credentialService.getAccess(databaseId, getId(principal)); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseAccessDto access = cacheService.getAccess(databaseId, getId(principal)); endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(access.getType(), table.getOwner().getId(), getId(principal)); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.deleteTuple(table, data); + tableService.deleteTuple(database, table, data); metadataServiceGateway.updateTableStatistics(databaseId, tableId, authorization); return ResponseEntity.status(HttpStatus.ACCEPTED) .build(); @@ -504,7 +512,7 @@ public class TableEndpoint extends RestEndpoint { @RequestParam(value = "size", required = false) Long size, Principal principal) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, NotAllowedException, MetadataServiceException, - PaginationException { + PaginationException, DatabaseNotFoundException { log.debug("endpoint find table history, databaseId={}, tableId={}", databaseId, tableId); if (size != null && size <= 0) { log.error("Invalid size: must be > 0"); @@ -513,16 +521,17 @@ public class TableEndpoint extends RestEndpoint { log.debug("size not set: default to 100L"); size = 100L; } - final TableDto table = credentialService.getTable(databaseId, tableId); + final TableDto table = cacheService.getTable(databaseId, tableId); if (!table.getIsPublic()) { if (principal == null) { log.error("Failed to find table history: no authentication found"); throw new NotAllowedException("Failed to find table history: no authentication found"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - final List<TableHistoryDto> dto = tableService.history(table, size); + final List<TableHistoryDto> dto = tableService.history(database, table, size); return ResponseEntity.status(HttpStatus.OK) .body(dto); } catch (SQLException e) { @@ -572,7 +581,7 @@ public class TableEndpoint extends RestEndpoint { throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, DatabaseMalformedException, TableNotFoundException, MetadataServiceException { log.debug("endpoint inspect table schemas, databaseId={}", databaseId); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { return ResponseEntity.ok(databaseService.exploreTables(database)); } catch (SQLException e) { @@ -625,17 +634,18 @@ public class TableEndpoint extends RestEndpoint { timestamp = Instant.now(); log.debug("timestamp not set: default to {}", timestamp); } - final TableDto table = credentialService.getTable(databaseId, tableId); + final TableDto table = cacheService.getTable(databaseId, tableId); if (!table.getIsPublic()) { if (principal == null) { log.error("Failed to export private table: principal is null"); throw new NotAllowedException("Failed to export private table: principal is null"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } - final String query = mariaDbMapper.defaultRawSelectQuery(table.getDatabase().getInternalName(), + final DatabaseDto database = cacheService.getDatabase(databaseId); + final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), table.getInternalName(), timestamp, null, null); - final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(table.getTdbid()), + final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(table.getDatabaseId()), query); metricsService.countTableGetData(databaseId, tableId); final ExportResourceDto resource = storageService.transformDataset(dataset); @@ -684,17 +694,18 @@ public class TableEndpoint extends RestEndpoint { @RequestHeader("Authorization") String authorization) throws RemoteUnavailableException, TableNotFoundException, NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, StorageUnavailableException, QueryMalformedException, - DatabaseUnavailableException { + DatabaseUnavailableException, DatabaseNotFoundException { log.debug("endpoint insert table data, databaseId={}, tableId={}, data.location={}", databaseId, tableId, data.getLocation()); - final TableDto table = credentialService.getTable(databaseId, tableId); - final DatabaseAccessDto access = credentialService.getAccess(databaseId, getId(principal)); + final TableDto table = cacheService.getTable(databaseId, tableId); + final DatabaseAccessDto access = cacheService.getAccess(databaseId, getId(principal)); endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(access.getType(), table.getOwner().getId(), getId(principal)); if (data.getLineTermination() == null) { data.setLineTermination("\\r\\n"); log.debug("line termination not present, default to {}", data.getLineTermination()); } + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - tableService.importDataset(table, data); + tableService.importDataset(database, table, data); } catch (SQLException | TableMalformedException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); throw new DatabaseUnavailableException("Failed to establish connection to database", e); @@ -734,11 +745,11 @@ public class TableEndpoint extends RestEndpoint { public ResponseEntity<TableStatisticDto> statistic(@NotNull @PathVariable("databaseId") UUID databaseId, @NotNull @PathVariable("tableId") UUID tableId) throws DatabaseUnavailableException, RemoteUnavailableException, TableNotFoundException, - MetadataServiceException, TableMalformedException { + MetadataServiceException, TableMalformedException, DatabaseNotFoundException { log.debug("endpoint generate table statistic, databaseId={}, tableId={}", databaseId, tableId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - return ResponseEntity.ok(tableService.getStatistics( - credentialService.getTable(databaseId, tableId))); + return ResponseEntity.ok(tableService.getStatistics(database, cacheService.getTable(databaseId, tableId))); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); throw new DatabaseUnavailableException("Failed to establish connection to database", e); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 47b4bb81db2371e42eefd546937af97314bfef5d..430ac4edc5e00aa2a65a22ce8a07fb2a909bf486 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -46,25 +46,25 @@ import java.util.UUID; public class ViewEndpoint extends RestEndpoint { private final ViewService viewService; + private final CacheService cacheService; private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; - private final CredentialService credentialService; private final EndpointValidator endpointValidator; @Autowired - public ViewEndpoint(ViewService viewService, MariaDbMapper mariaDbMapper, SubsetService subsetService, - MetricsService metricsService, StorageService storageService, DatabaseService databaseService, - CredentialService credentialService, EndpointValidator endpointValidator) { + public ViewEndpoint(ViewService viewService, CacheService cacheService, MariaDbMapper mariaDbMapper, + SubsetService subsetService, MetricsService metricsService, StorageService storageService, + DatabaseService databaseService, EndpointValidator endpointValidator) { this.viewService = viewService; + this.cacheService = cacheService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; - this.credentialService = credentialService; this.endpointValidator = endpointValidator; } @@ -109,7 +109,7 @@ public class ViewEndpoint extends RestEndpoint { throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException, DatabaseMalformedException, MetadataServiceException, ViewNotFoundException { log.debug("endpoint inspect view schemas, databaseId={}", databaseId); - final DatabaseDto database = credentialService.getDatabase(databaseId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { return ResponseEntity.ok(databaseService.exploreViews(database)); } catch (SQLException e) { @@ -152,12 +152,17 @@ public class ViewEndpoint extends RestEndpoint { }) public ResponseEntity<ViewDto> create(@NotNull @PathVariable("databaseId") UUID databaseId, @Valid @RequestBody CreateViewDto data) throws DatabaseUnavailableException, - DatabaseNotFoundException, RemoteUnavailableException, ViewMalformedException, MetadataServiceException { + DatabaseNotFoundException, RemoteUnavailableException, ViewMalformedException, MetadataServiceException, + TableNotFoundException, ImageNotFoundException, QueryMalformedException { log.debug("endpoint create view, databaseId={}, data.name={}", databaseId, data.getName()); - final DatabaseDto database = credentialService.getDatabase(databaseId); + /* check */ + endpointValidator.validateSubsetParams(data.getQuery()); + /* create */ + final DatabaseDto database = cacheService.getDatabase(databaseId); try { return ResponseEntity.status(HttpStatus.CREATED) - .body(databaseService.createView(database, data)); + .body(databaseService.createView(database, mariaDbMapper.nameToInternalName(data.getName()), + mariaDbMapper.subsetDtoToRawQuery(database, data.getQuery()))); } catch (SQLException e) { log.error("Failed to establish connection to database: {}", e.getMessage()); throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e); @@ -196,11 +201,12 @@ public class ViewEndpoint extends RestEndpoint { public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") UUID databaseId, @NotNull @PathVariable("viewId") UUID viewId) throws DatabaseUnavailableException, RemoteUnavailableException, ViewNotFoundException, - ViewMalformedException, MetadataServiceException { + ViewMalformedException, MetadataServiceException, DatabaseNotFoundException { log.debug("endpoint delete view, databaseId={}, viewId={}", databaseId, viewId); - final ViewDto view = credentialService.getView(databaseId, viewId); + final ViewDto view = cacheService.getView(databaseId, viewId); + final DatabaseDto database = cacheService.getDatabase(databaseId); try { - viewService.delete(view); + viewService.delete(database, view); return ResponseEntity.status(HttpStatus.ACCEPTED) .build(); } catch (SQLException e) { @@ -273,28 +279,29 @@ public class ViewEndpoint extends RestEndpoint { timestamp = Instant.now(); log.debug("timestamp not set: default to {}", timestamp); } - final ViewDto view = credentialService.getView(databaseId, viewId); + final ViewDto view = cacheService.getView(databaseId, viewId); if (!view.getIsPublic()) { if (principal == null) { log.error("Failed to get data from view: unauthorized"); throw new NotAllowedException("Failed to get data from view: unauthorized"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } + final DatabaseDto database = cacheService.getDatabase(databaseId); try { final HttpHeaders headers = new HttpHeaders(); if (request.getMethod().equals("HEAD")) { headers.set("Access-Control-Expose-Headers", "X-Count"); - headers.set("X-Count", "" + viewService.count(view, timestamp)); + headers.set("X-Count", "" + viewService.count(database, view, timestamp)); return ResponseEntity.ok() .headers(headers) .build(); } headers.set("Access-Control-Expose-Headers", "X-Headers"); headers.set("X-Headers", String.join(",", view.getColumns().stream().map(ViewColumnDto::getInternalName).toList())); - final String query = mariaDbMapper.defaultRawSelectQuery(view.getDatabase().getInternalName(), + final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), view.getInternalName(), timestamp, page, size); - final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(databaseId), + final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId), query); metricsService.countViewGetData(databaseId, viewId); return ResponseEntity.ok() @@ -351,17 +358,18 @@ public class ViewEndpoint extends RestEndpoint { log.debug("timestamp not set: default to {}", timestamp); } /* parameters */ - final ViewDto view = credentialService.getView(databaseId, viewId); + final ViewDto view = cacheService.getView(databaseId, viewId); if (!view.getIsPublic()) { if (principal == null) { log.error("Failed to export private view: principal is null"); throw new NotAllowedException("Failed to export private view: principal is null"); } - credentialService.getAccess(databaseId, getId(principal)); + cacheService.getAccess(databaseId, getId(principal)); } - final String query = mariaDbMapper.defaultRawSelectQuery(view.getDatabase().getInternalName(), + final DatabaseDto database = cacheService.getDatabase(databaseId); + final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), view.getInternalName(), timestamp, null, null); - final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(databaseId), + final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId), query); metricsService.countViewGetData(databaseId, viewId); final ExportResourceDto resource = storageService.transformDataset(dataset); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java index cf3f25fd2632e8427bf21afdc59634b4c46b91f6..0926b1cf023a8a67b1712b7f2e2283c58083273c 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java @@ -458,6 +458,13 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } + @Hidden + @ResponseStatus(code = HttpStatus.CONFLICT) + @ExceptionHandler(ViewExistsException.class) + public ResponseEntity<ApiErrorDto> handle(ViewExistsException e) { + return generic_handle(e.getClass(), e.getLocalizedMessage()); + } + @Hidden @ResponseStatus(code = HttpStatus.BAD_REQUEST) @ExceptionHandler(ViewMalformedException.class) diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java index 9ad13f5be68bf6714f5d18fec4973fe9898b38f6..ebb39f7c1879e354233a163c4ef677376ee2e44b 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java @@ -3,10 +3,13 @@ package at.tuwien.validation; import at.tuwien.api.database.AccessTypeDto; import at.tuwien.api.database.DatabaseAccessDto; import at.tuwien.api.database.DatabaseDto; +import at.tuwien.api.database.query.FilterDto; +import at.tuwien.api.database.query.FilterTypeDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.config.QueryConfig; import at.tuwien.endpoints.RestEndpoint; import at.tuwien.exception.*; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -24,10 +27,10 @@ import java.util.regex.Pattern; public class EndpointValidator extends RestEndpoint { private final QueryConfig queryConfig; - private final CredentialService credentialService; + private final CacheService credentialService; @Autowired - public EndpointValidator(QueryConfig queryConfig, CredentialService credentialService) { + public EndpointValidator(QueryConfig queryConfig, CacheService credentialService) { this.queryConfig = queryConfig; this.credentialService = credentialService; } @@ -63,6 +66,22 @@ public class EndpointValidator extends RestEndpoint { validateOnlyAccess(database, principal, writeAccessOnly); } + public void validateSubsetParams(SubsetDto subset) throws QueryMalformedException { + if (subset.getFilter() != null) { + final List<FilterDto> filters = subset.getFilter(); + FilterTypeDto previous = null; + for (int i = 0; i < filters.size(); i++) { + final FilterDto filter = filters.get(i); + if ((i == 0 && !filter.getType().equals(FilterTypeDto.WHERE)) || + (i > 0 && !previous.equals(FilterTypeDto.WHERE) && (filter.getType().equals(FilterTypeDto.AND) || filter.getType().equals(FilterTypeDto.OR)))) { + log.error("Failed to validate subset: invalid specification, must be where-[(and|or)-where]"); + throw new QueryMalformedException("Failed to validate subset: invalid specification, must be where-[(and|or)-where]"); + } + previous = filter.getType(); + } + } + } + public void validateOnlyPrivateSchemaHasRole(DatabaseDto database, Principal principal, String role) throws NotAllowedException { if (database.getIsSchemaPublic()) { diff --git a/dbrepo-data-service/rest-service/src/main/resources/init/querystore.sql b/dbrepo-data-service/rest-service/src/main/resources/init/querystore.sql deleted file mode 100644 index de488f89ee3b9b24426927bb114a3e73f4d6daf0..0000000000000000000000000000000000000000 --- a/dbrepo-data-service/rest-service/src/main/resources/init/querystore.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE PROCEDURE hash_table(IN name VARCHAR(255), OUT hash VARCHAR(255), OUT count BIGINT) BEGIN DECLARE _sql TEXT; SELECT CONCAT('SELECT SHA2(GROUP_CONCAT(CONCAT_WS(\'\',', GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name), ') SEPARATOR \',\'), 256) AS hash, COUNT(*) AS count FROM `', name, '` INTO @hash, @count;') FROM `information_schema`.`columns` WHERE `table_schema` = DATABASE() AND `table_name` = name INTO _sql; PREPARE stmt FROM _sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET hash = @hash; SET count = @count; END; -CREATE PROCEDURE store_query(IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _username varchar(255) DEFAULT REGEXP_REPLACE(current_user(), '@.*', ''); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END; -CREATE DEFINER = 'root' PROCEDURE _store_query(IN _username VARCHAR(255), IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END; \ No newline at end of file diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java index 709e3893867dd12eaddde505cb80e4667de14d8c..e03ea299a229c41ee6a5a5c342ea7af69ebc4bd4 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java @@ -30,10 +30,10 @@ public class MariaDbConfig { log.debug("created database {}", database); } - public static void createInitDatabase(ContainerDto container, DatabaseDto database) throws SQLException { - final String jdbc = "jdbc:mariadb://" + container.getHost() + ":" + container.getPort(); + public static void createInitDatabase(DatabaseDto database) throws SQLException { + final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort(); log.trace("connect to database {}", jdbc); - try (Connection connection = DriverManager.getConnection(jdbc, container.getUsername(), container.getPassword())) { + try (Connection connection = DriverManager.getConnection(jdbc, database.getContainer().getUsername(), database.getContainer().getPassword())) { ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("init/" + database.getInternalName() + ".sql"), new ClassPathResource("init/users.sql"), new ClassPathResource("init/querystore.sql")); populator.setSeparator(";\n"); populator.populate(connection); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java index 3cbdf09af1f7705b2dd3fa550c24770618ba99d1..d41e0609bae2f356a68dd5baddee150d73356a68 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/AccessEndpointUnitTest.java @@ -6,7 +6,7 @@ import at.tuwien.api.user.UserDto; import at.tuwien.endpoints.AccessEndpoint; import at.tuwien.exception.*; import at.tuwien.service.AccessService; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -34,7 +34,7 @@ public class AccessEndpointUnitTest extends AbstractUnitTest { private AccessEndpoint accessEndpoint; @MockBean - private CredentialService credentialService; + private CacheService credentialService; @MockBean private AccessService accessService; diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java index 43f7b9353e0381a6bc001b1a563036e20e8daae1..e2a6c550d04a62dcc08fb2603c50c7c05af750c9 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/DatabaseEndpointUnitTest.java @@ -7,7 +7,7 @@ import at.tuwien.endpoints.DatabaseEndpoint; import at.tuwien.exception.*; import at.tuwien.service.AccessService; import at.tuwien.service.ContainerService; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.DatabaseService; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; @@ -48,7 +48,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { private DatabaseService databaseService; @MockBean - private CredentialService credentialService; + private CacheService credentialService; @BeforeEach public void beforeEach() { diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java index f29226406040247bd274c0562d4d2d99dff9d278..b72bceafd1dfb22c67439847492624394cae81ba 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java @@ -1,13 +1,12 @@ package at.tuwien.endpoint; -import at.tuwien.api.database.CreateViewDto; import at.tuwien.api.database.DatabaseDto; -import at.tuwien.api.database.query.ExecuteStatementDto; import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryPersistDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.endpoints.SubsetEndpoint; import at.tuwien.exception.*; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.DatabaseService; import at.tuwien.service.StorageService; import at.tuwien.service.SubsetService; @@ -37,6 +36,7 @@ import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @Log4j2 @@ -63,7 +63,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { private DatabaseService databaseService; @MockBean - private CredentialService credentialService; + private CacheService credentialService; @BeforeEach public void beforeEach() { @@ -162,6 +162,23 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { generic_findById(DATABASE_1_ID, QUERY_1_ID, "application/json", null, USER_1_PRINCIPAL); } + @Test + @WithMockUser(username = USER_1_USERNAME) + public void findById_privateDataPrivateSchemaAcceptEmpty_succeeds() throws DatabaseNotFoundException, SQLException, + RemoteUnavailableException, UserNotFoundException, QueryNotFoundException, MetadataServiceException, + DatabaseUnavailableException, TableNotFoundException, StorageUnavailableException, NotAllowedException, + QueryMalformedException, FormatNotAvailableException { + + /* mock */ + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); + when(subsetService.findById(DATABASE_1_PRIVILEGED_DTO, QUERY_1_ID)) + .thenReturn(QUERY_1_DTO); + + /* test */ + generic_findById(DATABASE_1_ID, QUERY_1_ID, null, null, USER_1_PRINCIPAL); + } + @Test @WithMockUser(username = USER_3_USERNAME) public void findById_publicDataPrivateSchema_succeeds() throws DatabaseNotFoundException, SQLException, @@ -296,20 +313,18 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { TableMalformedException, NotAllowedException, QueryNotSupportedException, PaginationException, StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException, SQLException, QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException, - MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException { + MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException, + ImageNotFoundException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_5_STATEMENT) - .build(); /* mock */ when(credentialService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); - when(subsetService.findById(eq(DATABASE_3_PRIVILEGED_DTO), any(UUID.class))) + when(subsetService.findById(any(DatabaseDto.class), any(UUID.class))) .thenReturn(QUERY_5_DTO); - when(subsetService.create(eq(DATABASE_3_PRIVILEGED_DTO), eq(QUERY_5_STATEMENT), any(Instant.class), any(UUID.class))) + when(subsetService.create(any(DatabaseDto.class), any(SubsetDto.class), any(Instant.class), any(UUID.class))) .thenReturn(QUERY_5_ID); when(databaseService.inspectView(any(DatabaseDto.class), anyString())) .thenReturn(QUERY_5_VIEW_DTO); @@ -317,24 +332,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn("POST"); /* test */ - subsetEndpoint.create(DATABASE_3_ID, request, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L); - } - - @Test - @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query"}) - public void create_forbiddenKeyword_fails() { - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement("SELECT COUNT(id) FROM tbl") - .build(); - - /* mock */ - when(httpServletRequest.getMethod()) - .thenReturn("POST"); - - /* test */ - assertThrows(QueryNotSupportedException.class, () -> { - subsetEndpoint.create(DATABASE_3_ID, request, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L); - }); + subsetEndpoint.create(DATABASE_3_ID, QUERY_5_SUBSET_DTO, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L); } @Test @@ -344,22 +342,19 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { PaginationException, StorageNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException, RemoteUnavailableException, SQLException, MetadataServiceException, TableNotFoundException, ViewMalformedException, - ViewNotFoundException { + ViewNotFoundException, ImageNotFoundException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_5_STATEMENT) - .build(); /* mock */ when(credentialService.getDatabase(DATABASE_3_ID)) .thenReturn(DATABASE_3_PRIVILEGED_DTO); - when(subsetService.create(any(DatabaseDto.class), eq(QUERY_5_STATEMENT), any(Instant.class), eq(USER_1_ID))) + when(subsetService.create(any(DatabaseDto.class), any(SubsetDto.class), any(Instant.class), eq(USER_1_ID))) .thenReturn(QUERY_5_ID); when(subsetService.findById(any(DatabaseDto.class), eq(QUERY_5_ID))) .thenReturn(QUERY_5_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); - when(databaseService.createView(any(DatabaseDto.class), any(CreateViewDto.class))) + when(databaseService.createView(any(DatabaseDto.class), anyString(), anyString())) .thenReturn(QUERY_5_VIEW_DTO); when(databaseService.inspectView(any(DatabaseDto.class), anyString())) .thenReturn(QUERY_5_VIEW_DTO); @@ -367,16 +362,13 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn("POST"); /* test */ - subsetEndpoint.create(DATABASE_3_ID, request, USER_1_PRINCIPAL, httpServletRequest, null, null, null); + subsetEndpoint.create(DATABASE_3_ID, QUERY_5_SUBSET_DTO, USER_1_PRINCIPAL, httpServletRequest, null, null, null); } @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query"}) public void create_databaseNotFound_fails() throws RemoteUnavailableException, DatabaseNotFoundException, MetadataServiceException { - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_5_STATEMENT) - .build(); /* mock */ doThrow(DatabaseNotFoundException.class) @@ -387,38 +379,36 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - subsetEndpoint.create(DATABASE_3_ID, request, USER_1_PRINCIPAL, httpServletRequest, null, null, null); + subsetEndpoint.create(DATABASE_3_ID, QUERY_5_SUBSET_DTO, USER_1_PRINCIPAL, httpServletRequest, null, null, null); }); } @Test @WithAnonymousUser - public void create_publicDataPublicSchemaAnonymous_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, - MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, - NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, - StorageUnavailableException, QueryMalformedException, QueryNotSupportedException, PaginationException, - StorageNotFoundException, TableNotFoundException, ViewMalformedException, ViewNotFoundException { + public void create_publicDataPublicSchemaAnonymous_succeeds() throws DatabaseNotFoundException, + RemoteUnavailableException, MetadataServiceException, UserNotFoundException, QueryStoreInsertException, + TableMalformedException, NotAllowedException, SQLException, QueryNotFoundException, PaginationException, + DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, + QueryNotSupportedException, StorageNotFoundException, TableNotFoundException, ViewMalformedException, + ViewNotFoundException, ImageNotFoundException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_5_STATEMENT) - .build(); /* mock */ when(credentialService.getDatabase(DATABASE_4_ID)) .thenReturn(DATABASE_4_PRIVILEGED_DTO); when(subsetService.findById(eq(DATABASE_4_PRIVILEGED_DTO), any(UUID.class))) - .thenReturn(QUERY_5_DTO); - when(subsetService.create(eq(DATABASE_4_PRIVILEGED_DTO), eq(QUERY_5_STATEMENT), any(Instant.class), eq(null))) - .thenReturn(QUERY_5_ID); + .thenReturn(QUERY_9_DTO); + when(subsetService.create(eq(DATABASE_4_PRIVILEGED_DTO), any(SubsetDto.class), any(Instant.class), eq(null))) + .thenReturn(QUERY_9_ID); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); when(databaseService.inspectView(any(DatabaseDto.class), anyString())) - .thenReturn(QUERY_5_VIEW_DTO); + .thenReturn(QUERY_9_VIEW_DTO); when(httpServletRequest.getMethod()) .thenReturn("POST"); /* test */ - subsetEndpoint.create(DATABASE_4_ID, request, null, httpServletRequest, null, null, null); + subsetEndpoint.create(DATABASE_4_ID, QUERY_9_SUBSET_DTO, null, httpServletRequest, null, null, null); } @Test @@ -427,18 +417,16 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { MetadataServiceException, UserNotFoundException, QueryStoreInsertException, TableMalformedException, NotAllowedException, SQLException, QueryNotFoundException, DatabaseUnavailableException, StorageUnavailableException, QueryMalformedException, QueryNotSupportedException, PaginationException, - StorageNotFoundException, TableNotFoundException, ViewMalformedException, ViewNotFoundException { + StorageNotFoundException, TableNotFoundException, ViewMalformedException, ViewNotFoundException, + ImageNotFoundException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_1_STATEMENT) - .build(); /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); - when(subsetService.findById(eq(DATABASE_1_PRIVILEGED_DTO), any(UUID.class))) + when(subsetService.findById(any(DatabaseDto.class), any(UUID.class))) .thenReturn(QUERY_1_DTO); - when(subsetService.create(eq(DATABASE_1_PRIVILEGED_DTO), eq(QUERY_1_STATEMENT), any(Instant.class), any(UUID.class))) + when(subsetService.create(any(DatabaseDto.class), any(SubsetDto.class), any(Instant.class), any(UUID.class))) .thenReturn(QUERY_1_ID); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); @@ -448,7 +436,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { .thenReturn("POST"); /* test */ - subsetEndpoint.create(DATABASE_1_ID, request, USER_1_PRINCIPAL, httpServletRequest, null, null, null); + subsetEndpoint.create(DATABASE_1_ID, QUERY_1_SUBSET_DTO, USER_1_PRINCIPAL, httpServletRequest, null, null, null); } @Test @@ -457,15 +445,12 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { MetadataServiceException, UserNotFoundException, QueryNotFoundException, QueryMalformedException, TableNotFoundException, RemoteUnavailableException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); - final ExecuteStatementDto request = ExecuteStatementDto.builder() - .statement(QUERY_5_STATEMENT) - .build(); /* mock */ when(credentialService.getDatabase(DATABASE_2_ID)) .thenReturn(DATABASE_2_PRIVILEGED_DTO); when(subsetService.findById(eq(DATABASE_2_PRIVILEGED_DTO), any(UUID.class))) - .thenReturn(QUERY_2_DTO); + .thenReturn(QUERY_8_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); when(httpServletRequest.getMethod()) @@ -473,13 +458,13 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - subsetEndpoint.create(DATABASE_2_ID, request, null, httpServletRequest, null, null, null); + subsetEndpoint.create(DATABASE_2_ID, QUERY_8_SUBSET_DTO, null, httpServletRequest, null, null, null); }); } @Test public void getData_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException, - NotAllowedException, SQLException, QueryNotFoundException, TableMalformedException, QueryMalformedException, + NotAllowedException, SQLException, QueryNotFoundException, QueryMalformedException, DatabaseUnavailableException, PaginationException, MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); @@ -531,9 +516,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME) public void getData_private_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, - UserNotFoundException, DatabaseUnavailableException, NotAllowedException, TableMalformedException, - QueryMalformedException, QueryNotFoundException, PaginationException, SQLException, - MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException { + UserNotFoundException, DatabaseUnavailableException, NotAllowedException, QueryMalformedException, + QueryNotFoundException, PaginationException, SQLException, MetadataServiceException, + TableNotFoundException, ViewNotFoundException, ViewMalformedException { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ @@ -592,9 +577,9 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME) public void getData_privateHead_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, - UserNotFoundException, DatabaseUnavailableException, NotAllowedException, TableMalformedException, - QueryMalformedException, QueryNotFoundException, PaginationException, SQLException, - MetadataServiceException, TableNotFoundException, ViewNotFoundException, ViewMalformedException { + UserNotFoundException, DatabaseUnavailableException, NotAllowedException, QueryMalformedException, + QueryNotFoundException, PaginationException, SQLException, MetadataServiceException, + TableNotFoundException, ViewNotFoundException, ViewMalformedException { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java index 57e6ede962cec6fa7f97721bc0089604ee900eff..25f3b60ceac1f47225e73c237cefc215c21f1696 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java @@ -4,10 +4,11 @@ import at.tuwien.api.database.DatabaseAccessDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.table.*; +import at.tuwien.api.database.table.internal.TableCreateDto; import at.tuwien.endpoints.TableEndpoint; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.DatabaseService; import at.tuwien.service.SubsetService; import at.tuwien.service.TableService; @@ -68,7 +69,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { private DatabaseService databaseService; @MockBean - private CredentialService credentialService; + private CacheService credentialService; @MockBean private MetadataServiceGateway metadataServiceGateway; @@ -103,10 +104,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); - when(databaseService.createTable(DATABASE_1_PRIVILEGED_DTO, TABLE_4_CREATE_INTERNAL_DTO)) - .thenReturn(TABLE_4_PRIVILEGED_DTO); - when(databaseService.inspectTable(DATABASE_1_PRIVILEGED_DTO, TABLE_4_INTERNALNAME)) - .thenReturn(TABLE_4_PRIVILEGED_DTO); + when(databaseService.createTable(any(DatabaseDto.class), any(TableCreateDto.class))) + .thenReturn(TABLE_4_DTO); + when(databaseService.inspectTable(any(DatabaseDto.class), anyString())) + .thenReturn(TABLE_4_DTO); /* test */ final ResponseEntity<TableDto> response = tableEndpoint.create(DATABASE_1_ID, TABLE_4_CREATE_INTERNAL_DTO); @@ -170,12 +171,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void statistic_succeeds() throws DatabaseUnavailableException, TableNotFoundException, SQLException, - TableMalformedException, RemoteUnavailableException, MetadataServiceException { + TableMalformedException, RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(tableService.getStatistics(any(TableDto.class))) + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(tableService.getStatistics(any(DatabaseDto.class), any(TableDto.class))) .thenReturn(TABLE_8_STATISTIC_DTO); /* test */ @@ -186,14 +189,16 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void statistic_unavailable_fails() throws TableNotFoundException, TableMalformedException, - RemoteUnavailableException, MetadataServiceException, SQLException { + RemoteUnavailableException, MetadataServiceException, SQLException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(SQLException.class) .when(tableService) - .getStatistics(any(TableDto.class)); + .getStatistics(any(DatabaseDto.class), any(TableDto.class)); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -220,14 +225,17 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) public void delete_succeeds() throws RemoteUnavailableException, DatabaseUnavailableException, - TableNotFoundException, QueryMalformedException, SQLException, MetadataServiceException { + TableNotFoundException, QueryMalformedException, SQLException, MetadataServiceException, + DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doNothing() .when(tableService) - .delete(TABLE_1_PRIVILEGED_DTO); + .delete(DATABASE_1_DTO, TABLE_1_DTO); /* test */ final ResponseEntity<Void> response = tableEndpoint.delete(DATABASE_1_ID, TABLE_1_ID); @@ -263,14 +271,16 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) public void delete_unavailable_fails() throws RemoteUnavailableException, TableNotFoundException, SQLException, - MetadataServiceException, QueryMalformedException { + MetadataServiceException, QueryMalformedException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(SQLException.class) .when(tableService) - .delete(TABLE_1_PRIVILEGED_DTO); + .delete(any(DatabaseDto.class), any(TableDto.class)); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -286,17 +296,17 @@ public class TableEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(credentialService.getDatabase(DATABASE_3_ID)) - .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(credentialService.getTable(DATABASE_1_ID, TABLE_4_ID)) + .thenReturn(TABLE_4_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); when(httpServletRequest.getMethod()) .thenReturn("GET"); /* test */ - final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null); + final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_1_ID, TABLE_4_ID, null, null, null, httpServletRequest, null); assertEquals(HttpStatus.OK, response.getStatusCode()); } @@ -309,17 +319,19 @@ public class TableEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(tableService.getCount(eq(TABLE_8_PRIVILEGED_DTO), any(Instant.class))) + when(credentialService.getTable(DATABASE_2_ID, TABLE_5_ID)) + .thenReturn(TABLE_5_DTO); + when(credentialService.getDatabase(DATABASE_2_ID)) + .thenReturn(DATABASE_2_PRIVILEGED_DTO); + when(tableService.getCount(any(DatabaseDto.class), any(TableDto.class), any(Instant.class))) .thenReturn(3L); - when(subsetService.getData(eq(DATABASE_3_PRIVILEGED_DTO), anyString())) + when(subsetService.getData(eq(DATABASE_2_DTO), anyString())) .thenReturn(mock); when(httpServletRequest.getMethod()) .thenReturn("HEAD"); /* test */ - final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null); + final ResponseEntity<List<Map<String, Object>>> response = tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, httpServletRequest, null); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getHeaders().get("Access-Control-Expose-Headers")); assertEquals("X-Count", response.getHeaders().get("Access-Control-Expose-Headers").get(0)); @@ -335,7 +347,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); /* test */ assertThrows(NotAllowedException.class, () -> { @@ -350,7 +362,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_2_ID); @@ -361,16 +373,33 @@ public class TableEndpointUnitTest extends AbstractUnitTest { }); } + @Test + @WithAnonymousUser + public void getData_notAllowed_fails() throws TableNotFoundException, RemoteUnavailableException, + MetadataServiceException{ + + /* mock */ + when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) + .thenReturn(TABLE_8_DTO); + when(httpServletRequest.getMethod()) + .thenReturn("GET"); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null); + }); + } + @Test @WithAnonymousUser public void getData_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, MetadataServiceException, QueryMalformedException, DatabaseNotFoundException { /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(credentialService.getDatabase(DATABASE_3_ID)) - .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(credentialService.getTable(DATABASE_2_ID, TABLE_5_ID)) + .thenReturn(TABLE_5_DTO); + when(credentialService.getDatabase(DATABASE_2_ID)) + .thenReturn(DATABASE_2_DTO); doThrow(QueryMalformedException.class) .when(subsetService) .getData(any(DatabaseDto.class), anyString()); @@ -379,7 +408,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(DatabaseUnavailableException.class, () -> { - tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null); + tableEndpoint.getData(DATABASE_2_ID, TABLE_5_ID, null, null, null, httpServletRequest, null); }); } @@ -390,7 +419,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); doThrow(RemoteUnavailableException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_2_ID); @@ -411,7 +440,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); when(credentialService.getDatabase(DATABASE_1_ID)) .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) @@ -446,7 +475,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_succeeds() throws DatabaseUnavailableException, TableNotFoundException, TableMalformedException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, - SQLException, StorageUnavailableException, StorageNotFoundException, MetadataServiceException { + SQLException, StorageUnavailableException, StorageNotFoundException, MetadataServiceException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -456,12 +485,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .createTuple(TABLE_8_PRIVILEGED_DTO, request); + .createTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -473,7 +504,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME) - public void insertRawTuple_noRole_fails() { + public void insertRawTuple_noRole_fails() throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -481,6 +513,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { }}) .build(); + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { tableEndpoint.insertRawTuple(DATABASE_3_ID, TABLE_8_ID, request, USER_3_PRINCIPAL, TOKEN_ACCESS_TOKEN); @@ -490,7 +526,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -499,6 +535,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(TableNotFoundException.class) .when(credentialService) .getTable(DATABASE_3_ID, TABLE_8_ID); @@ -512,7 +550,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -522,7 +560,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); @@ -536,7 +576,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException, TableMalformedException, StorageUnavailableException, - SQLException, QueryMalformedException, StorageNotFoundException { + SQLException, QueryMalformedException, StorageNotFoundException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -546,12 +586,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doThrow(SQLException.class) .when(tableService) - .createTuple(TABLE_8_PRIVILEGED_DTO, request); + .createTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -563,7 +605,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_writeOwnAccess_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException, - StorageUnavailableException, StorageNotFoundException, MetadataServiceException { + StorageUnavailableException, StorageNotFoundException, MetadataServiceException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -573,7 +615,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); @@ -584,7 +628,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void insertRawTuple_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -594,7 +638,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); @@ -606,9 +652,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) - public void insertRawTuple_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException, - StorageUnavailableException, StorageNotFoundException, MetadataServiceException { + public void insertRawTuple_writeAllAccessForeign_succeeds() throws TableNotFoundException, + RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, TableMalformedException, + QueryMalformedException, StorageUnavailableException, StorageNotFoundException, MetadataServiceException, + DatabaseNotFoundException { final TupleDto request = TupleDto.builder() .data(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 7L); @@ -618,7 +665,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); @@ -630,7 +679,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_succeeds() throws DatabaseUnavailableException, TableNotFoundException, TableMalformedException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, - SQLException, MetadataServiceException { + SQLException, MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -643,12 +692,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .updateTuple(TABLE_8_PRIVILEGED_DTO, request); + .updateTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -660,7 +711,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME) - public void updateTuple_noRole_fails() { + public void updateTuple_noRole_fails() throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -671,6 +723,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { }}) .build(); + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { tableEndpoint.updateRawTuple(DATABASE_3_ID, TABLE_8_ID, request, USER_3_PRINCIPAL, TOKEN_ACCESS_TOKEN); @@ -680,7 +736,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -692,6 +748,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(TableNotFoundException.class) .when(credentialService) .getTable(DATABASE_3_ID, TABLE_8_ID); @@ -705,7 +763,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -718,7 +776,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); @@ -731,7 +791,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, SQLException, - NotAllowedException, MetadataServiceException, TableMalformedException, QueryMalformedException { + NotAllowedException, MetadataServiceException, TableMalformedException, QueryMalformedException, + DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -744,12 +805,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); doThrow(SQLException.class) .when(tableService) - .updateTuple(TABLE_8_PRIVILEGED_DTO, request); + .updateTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -761,7 +824,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_writeOwnAccess_succeeds() throws DatabaseUnavailableException, TableNotFoundException, TableMalformedException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, - SQLException, MetadataServiceException { + SQLException, MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -774,12 +837,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .updateTuple(TABLE_8_PRIVILEGED_DTO, request); + .updateTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -789,10 +854,84 @@ public class TableEndpointUnitTest extends AbstractUnitTest { assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); } + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"system"}) + public void update_succeeds() throws DatabaseUnavailableException, TableNotFoundException, + TableMalformedException, RemoteUnavailableException, SQLException, MetadataServiceException, + DatabaseNotFoundException { + + /* mock */ + when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + doNothing() + .when(tableService) + .updateTable(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, TABLE_8_UPDATE_DTO); + + /* test */ + final ResponseEntity<TableDto> response = tableEndpoint.update(DATABASE_3_ID, TABLE_8_ID, TABLE_8_UPDATE_DTO); + assertEquals(HttpStatus.ACCEPTED, response.getStatusCode()); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"system"}) + public void update_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, + MetadataServiceException, DatabaseNotFoundException { + + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + doThrow(TableNotFoundException.class) + .when(credentialService) + .getTable(DATABASE_3_ID, TABLE_8_ID); + + /* test */ + assertThrows(TableNotFoundException.class, () -> { + tableEndpoint.update(DATABASE_3_ID, TABLE_8_ID, TABLE_8_UPDATE_DTO); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"system"}) + public void update_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, + MetadataServiceException, DatabaseNotFoundException { + + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + doThrow(RemoteUnavailableException.class) + .when(credentialService) + .getTable(DATABASE_3_ID, TABLE_8_ID); + + /* test */ + assertThrows(RemoteUnavailableException.class, () -> { + tableEndpoint.update(DATABASE_3_ID, TABLE_8_ID, TABLE_8_UPDATE_DTO); + }); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"system"}) + public void update_exception_fails() throws TableNotFoundException, RemoteUnavailableException, + MetadataServiceException, DatabaseNotFoundException { + + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + doThrow(MetadataServiceException.class) + .when(credentialService) + .getTable(DATABASE_3_ID, TABLE_8_ID); + + /* test */ + assertThrows(MetadataServiceException.class, () -> { + tableEndpoint.update(DATABASE_3_ID, TABLE_8_ID, TABLE_8_UPDATE_DTO); + }); + } + @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -805,7 +944,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); @@ -819,7 +960,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void updateTuple_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException, - SQLException, MetadataServiceException { + SQLException, MetadataServiceException, DatabaseNotFoundException { final TupleUpdateDto request = TupleUpdateDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -832,12 +973,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); doNothing() .when(tableService) - .updateTuple(TABLE_8_PRIVILEGED_DTO, request); + .updateTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -851,7 +994,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_succeeds() throws DatabaseUnavailableException, TableNotFoundException, TableMalformedException, NotAllowedException, QueryMalformedException, RemoteUnavailableException, - SQLException, MetadataServiceException { + SQLException, MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -860,12 +1003,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .deleteTuple(TABLE_8_PRIVILEGED_DTO, request); + .deleteTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -877,13 +1022,18 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME) - public void deleteTuple_noRole_fails() { + public void deleteTuple_noRole_fails() throws DatabaseNotFoundException, RemoteUnavailableException, + MetadataServiceException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); }}) .build(); + /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); + /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { tableEndpoint.deleteRawTuple(DATABASE_3_ID, TABLE_8_ID, request, USER_3_PRINCIPAL, TOKEN_ACCESS_TOKEN); @@ -893,7 +1043,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -901,6 +1051,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { .build(); /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(TableNotFoundException.class) .when(credentialService) .getTable(DATABASE_3_ID, TABLE_8_ID); @@ -914,7 +1066,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -923,7 +1075,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); @@ -936,7 +1090,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_unavailable_fails() throws TableNotFoundException, RemoteUnavailableException, SQLException, - NotAllowedException, MetadataServiceException, TableMalformedException, QueryMalformedException { + NotAllowedException, MetadataServiceException, TableMalformedException, QueryMalformedException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -945,12 +1099,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); doThrow(SQLException.class) .when(tableService) - .deleteTuple(TABLE_8_PRIVILEGED_DTO, request); + .deleteTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -962,7 +1118,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_writeOwnAccess_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, TableMalformedException, SQLException, QueryMalformedException, - DatabaseUnavailableException, MetadataServiceException { + DatabaseUnavailableException, MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -971,12 +1127,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .deleteTuple(TABLE_8_PRIVILEGED_DTO, request); + .deleteTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -989,7 +1147,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -998,7 +1156,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); @@ -1012,7 +1172,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"delete-table-data"}) public void deleteTuple_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException, - SQLException, MetadataServiceException { + SQLException, MetadataServiceException, DatabaseNotFoundException { final TupleDeleteDto request = TupleDeleteDto.builder() .keys(new HashMap<>() {{ put(COLUMN_8_1_INTERNAL_NAME, 6L); @@ -1021,12 +1181,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); doNothing() .when(tableService) - .deleteTuple(TABLE_8_PRIVILEGED_DTO, request); + .deleteTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -1039,27 +1201,31 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void getHistory_succeeds() throws DatabaseUnavailableException, TableNotFoundException, - RemoteUnavailableException, SQLException, NotAllowedException, MetadataServiceException, PaginationException { + RemoteUnavailableException, SQLException, NotAllowedException, MetadataServiceException, PaginationException, DatabaseNotFoundException { /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(tableService.history(TABLE_8_PRIVILEGED_DTO, null)) + when(credentialService.getTable(DATABASE_2_ID, TABLE_5_ID)) + .thenReturn(TABLE_5_DTO); + when(credentialService.getDatabase(DATABASE_2_ID)) + .thenReturn(DATABASE_2_PRIVILEGED_DTO); + when(tableService.history(DATABASE_2_PRIVILEGED_DTO, TABLE_5_DTO, null)) .thenReturn(List.of()); /* test */ - final ResponseEntity<List<TableHistoryDto>> response = tableEndpoint.getHistory(DATABASE_3_ID, TABLE_8_ID, null, null); + final ResponseEntity<List<TableHistoryDto>> response = tableEndpoint.getHistory(DATABASE_2_ID, TABLE_5_ID, null, null); assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @WithAnonymousUser public void getHistory_privateNoRole_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); /* test */ assertThrows(NotAllowedException.class, () -> { @@ -1081,11 +1247,13 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) public void getHistory_privateNoAccess_fails() throws NotAllowedException, RemoteUnavailableException, - TableNotFoundException, MetadataServiceException { + TableNotFoundException, MetadataServiceException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_4_ID); @@ -1099,14 +1267,15 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) public void getHistory_private_succeeds() throws NotAllowedException, RemoteUnavailableException, SQLException, - TableNotFoundException, MetadataServiceException, DatabaseUnavailableException, PaginationException { + TableNotFoundException, MetadataServiceException, DatabaseUnavailableException, PaginationException, + DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(DATABASE_1_USER_2_READ_ACCESS_DTO); - when(tableService.history(TABLE_1_PRIVILEGED_DTO, 10L)) + when(tableService.history(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, 10L)) .thenReturn(List.of()); /* test */ @@ -1117,27 +1286,31 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void getHistory_unavailable_succeeds() throws RemoteUnavailableException, SQLException, - TableNotFoundException, MetadataServiceException { + TableNotFoundException, MetadataServiceException, DatabaseNotFoundException { /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + when(credentialService.getTable(DATABASE_2_ID, TABLE_5_ID)) + .thenReturn(TABLE_5_DTO); + when(credentialService.getDatabase(DATABASE_2_ID)) + .thenReturn(DATABASE_2_PRIVILEGED_DTO); doThrow(SQLException.class) .when(tableService) - .history(TABLE_8_PRIVILEGED_DTO, 100L); + .history(any(DatabaseDto.class), any(TableDto.class), anyLong()); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { - tableEndpoint.getHistory(DATABASE_3_ID, TABLE_8_ID, null, null); + tableEndpoint.getHistory(DATABASE_2_ID, TABLE_5_ID, null, null); }); } @Test @WithAnonymousUser public void getHistory_tableNotFound_fails() throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { /* mock */ + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); doThrow(TableNotFoundException.class) .when(credentialService) .getTable(DATABASE_3_ID, TABLE_8_ID); @@ -1155,15 +1328,15 @@ public class TableEndpointUnitTest extends AbstractUnitTest { final Dataset<Row> mock = sparkSession.emptyDataFrame(); /* mock */ - when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); - when(credentialService.getDatabase(DATABASE_3_ID)) - .thenReturn(DATABASE_3_PRIVILEGED_DTO); + when(credentialService.getTable(DATABASE_1_ID, TABLE_4_ID)) + .thenReturn(TABLE_4_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); /* test */ - final ResponseEntity<InputStreamResource> response = tableEndpoint.exportDataset(DATABASE_3_ID, TABLE_8_ID, null, null); + final ResponseEntity<InputStreamResource> response = tableEndpoint.exportDataset(DATABASE_1_ID, TABLE_4_ID, null, null); assertEquals(HttpStatus.OK, response.getStatusCode()); } @@ -1177,11 +1350,13 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(access); when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) .thenReturn(mock); @@ -1193,11 +1368,13 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) public void exportData_privateNoAccess_fails() throws TableNotFoundException, NotAllowedException, - RemoteUnavailableException, MetadataServiceException { + RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_4_ID); @@ -1216,9 +1393,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_3_ID)) - .thenReturn(DATABASE_3_PRIVILEGED_DTO); - when(databaseService.exploreTables(DATABASE_3_PRIVILEGED_DTO)) - .thenReturn(List.of(TABLE_8_PRIVILEGED_DTO)); + .thenReturn(DATABASE_3_DTO); + when(databaseService.exploreTables(DATABASE_3_DTO)) + .thenReturn(List.of(TABLE_8_DTO)); /* test */ final ResponseEntity<List<TableDto>> response = tableEndpoint.getSchema(DATABASE_3_ID); @@ -1252,10 +1429,10 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_3_ID)) - .thenReturn(DATABASE_3_PRIVILEGED_DTO); + .thenReturn(DATABASE_3_DTO); doThrow(SQLException.class) .when(databaseService) - .exploreTables(DATABASE_3_PRIVILEGED_DTO); + .exploreTables(DATABASE_3_DTO); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -1266,7 +1443,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void importDataset_succeeds() throws TableNotFoundException, NotAllowedException, RemoteUnavailableException, - MetadataServiceException, StorageNotFoundException, MalformedException, StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, SQLException, TableMalformedException { + MetadataServiceException, StorageNotFoundException, MalformedException, StorageUnavailableException, + DatabaseUnavailableException, QueryMalformedException, SQLException, TableMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination(null) @@ -1275,12 +1454,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); doNothing() .when(tableService) - .importDataset(TABLE_8_PRIVILEGED_DTO, request); + .importDataset(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); doNothing() .when(metadataServiceGateway) .updateTableStatistics(DATABASE_3_ID, TABLE_8_ID, TOKEN_ACCESS_TOKEN); @@ -1330,7 +1511,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_unavailable_fails() throws RemoteUnavailableException, TableNotFoundException, MetadataServiceException, NotAllowedException, StorageNotFoundException, MalformedException, - StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException { + StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException, DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1339,12 +1520,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); doThrow(SQLException.class) .when(tableService) - .importDataset(any(TableDto.class), eq(request)); + .importDataset(any(DatabaseDto.class), any(TableDto.class), eq(request)); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -1356,7 +1539,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeOwnAccess_fails() throws RemoteUnavailableException, TableNotFoundException, MetadataServiceException, NotAllowedException, StorageNotFoundException, MalformedException, - StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException { + StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1365,12 +1549,14 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); doThrow(SQLException.class) .when(tableService) - .importDataset(any(TableDto.class), eq(request)); + .importDataset(any(DatabaseDto.class), any(TableDto.class), eq(request)); /* test */ assertThrows(NotAllowedException.class, () -> { @@ -1381,7 +1567,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_readAccess_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1390,7 +1576,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_READ_ACCESS_DTO); @@ -1404,7 +1592,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeOwnAccess_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, - StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1413,7 +1602,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_1_WRITE_OWN_ACCESS_DTO); @@ -1424,7 +1615,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeOwnAccessForeign_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1433,7 +1624,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_3_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_OWN_ACCESS_DTO); @@ -1447,7 +1640,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_3_USERNAME, authorities = {"insert-table-data"}) public void importDataset_writeAllAccessForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException, StorageNotFoundException, - MalformedException, StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { + MalformedException, StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1456,7 +1650,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID)) - .thenReturn(TABLE_8_PRIVILEGED_DTO); + .thenReturn(TABLE_8_DTO); + when(credentialService.getDatabase(DATABASE_3_ID)) + .thenReturn(DATABASE_3_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_3_ID, USER_1_ID)) .thenReturn(DATABASE_3_USER_3_WRITE_ALL_ACCESS_DTO); @@ -1468,7 +1664,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateForeign_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, - StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1477,7 +1674,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(DATABASE_1_USER_2_WRITE_ALL_ACCESS_DTO); @@ -1489,7 +1688,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_private_succeeds() throws TableNotFoundException, RemoteUnavailableException, NotAllowedException, MetadataServiceException, StorageNotFoundException, MalformedException, - StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException { + StorageUnavailableException, DatabaseUnavailableException, QueryMalformedException, + DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1498,7 +1698,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_2_ID)) - .thenReturn(TABLE_2_PRIVILEGED_DTO); + .thenReturn(TABLE_2_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(DATABASE_1_USER_2_WRITE_OWN_ACCESS_DTO); @@ -1509,7 +1711,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateForeign_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1518,7 +1720,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(DATABASE_1_USER_2_WRITE_OWN_ACCESS_DTO); @@ -1531,7 +1735,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME, authorities = {"insert-table-data"}) public void importDataset_privateReadAccess_fails() throws TableNotFoundException, RemoteUnavailableException, - NotAllowedException, MetadataServiceException { + NotAllowedException, MetadataServiceException, DatabaseNotFoundException { final ImportDto request = ImportDto.builder() .header(true) .lineTermination("\\n") @@ -1540,7 +1744,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_2_ID)) - .thenReturn(TABLE_2_PRIVILEGED_DTO); + .thenReturn(TABLE_2_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID)) .thenReturn(DATABASE_1_USER_2_READ_ACCESS_DTO); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java index 3421ed6124c284099eca5b72796ebdfd54c928f5..0393be3dad8da280f29cc1be9133ffa42c9f6cb2 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java @@ -4,7 +4,7 @@ import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.endpoints.ViewEndpoint; import at.tuwien.exception.*; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.DatabaseService; import at.tuwien.service.SubsetService; import at.tuwien.service.ViewService; @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @Log4j2 @@ -46,7 +47,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { private DatabaseService databaseService; @MockBean - private CredentialService credentialService; + private CacheService credentialService; @MockBean private HttpServletRequest httpServletRequest; @@ -68,13 +69,14 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) public void create_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, ViewMalformedException, - SQLException, DatabaseUnavailableException, MetadataServiceException { + SQLException, DatabaseUnavailableException, MetadataServiceException, TableNotFoundException, + ImageNotFoundException, QueryMalformedException { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); - when(databaseService.createView(DATABASE_1_PRIVILEGED_DTO, VIEW_1_CREATE_DTO)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); + when(databaseService.createView(any(DatabaseDto.class), anyString(), anyString())) + .thenReturn(VIEW_1_DTO); /* test */ final ResponseEntity<ViewDto> response = viewEndpoint.create(DATABASE_1_ID, VIEW_1_CREATE_DTO); @@ -88,10 +90,10 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); doThrow(SQLException.class) .when(databaseService) - .createView(DATABASE_1_PRIVILEGED_DTO, VIEW_1_CREATE_DTO); + .createView(any(DatabaseDto.class), anyString(), anyString()); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -106,9 +108,9 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); - when(databaseService.createView(DATABASE_1_PRIVILEGED_DTO, VIEW_1_CREATE_DTO)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); + when(databaseService.createView(DATABASE_1_DTO, VIEW_1_NAME, VIEW_1_QUERY)) + .thenReturn(VIEW_1_DTO); /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { @@ -139,8 +141,8 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); - when(databaseService.exploreViews(DATABASE_1_PRIVILEGED_DTO)) + .thenReturn(DATABASE_1_DTO); + when(databaseService.exploreViews(DATABASE_1_DTO)) .thenReturn(List.of(VIEW_1_DTO, VIEW_2_DTO, VIEW_3_DTO)); /* test */ @@ -181,10 +183,10 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); doThrow(SQLException.class) .when(databaseService) - .exploreViews(DATABASE_1_PRIVILEGED_DTO); + .exploreViews(DATABASE_1_DTO); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -205,14 +207,16 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) public void delete_succeeds() throws RemoteUnavailableException, ViewMalformedException, ViewNotFoundException, - SQLException, DatabaseUnavailableException, MetadataServiceException { + SQLException, DatabaseUnavailableException, MetadataServiceException, DatabaseNotFoundException { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doNothing() .when(viewService) - .delete(VIEW_1_PRIVILEGED_DTO); + .delete(DATABASE_1_PRIVILEGED_DTO, VIEW_1_DTO); /* test */ final ResponseEntity<Void> response = viewEndpoint.delete(DATABASE_1_ID, VIEW_1_ID); @@ -222,14 +226,16 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) public void delete_unavailable_fails() throws RemoteUnavailableException, ViewMalformedException, SQLException, - MetadataServiceException, ViewNotFoundException { + MetadataServiceException, ViewNotFoundException, DatabaseNotFoundException { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); doThrow(SQLException.class) .when(viewService) - .delete(VIEW_1_PRIVILEGED_DTO); + .delete(DATABASE_1_PRIVILEGED_DTO, VIEW_1_DTO); /* test */ assertThrows(DatabaseUnavailableException.class, () -> { @@ -247,7 +253,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { .thenReturn(DATABASE_1_PRIVILEGED_DTO); doNothing() .when(viewService) - .delete(VIEW_1_PRIVILEGED_DTO); + .delete(DATABASE_1_PRIVILEGED_DTO,VIEW_1_DTO); /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { @@ -280,9 +286,9 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); when(credentialService.getDatabase(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_1_ID)) .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO); when(subsetService.getData(any(DatabaseDto.class), anyString())) @@ -296,6 +302,31 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { assertNotNull(response.getBody()); } + @Test + @WithAnonymousUser + public void getData_privateDataPrivateSchemaAnonymous_fails() throws RemoteUnavailableException, + ViewNotFoundException, QueryMalformedException, NotAllowedException, MetadataServiceException, + TableNotFoundException, DatabaseNotFoundException { + final Dataset<Row> mock = sparkSession.emptyDataFrame(); + + /* mock */ + when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) + .thenReturn(VIEW_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); + when(credentialService.getAccess(DATABASE_1_ID, USER_1_ID)) + .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO); + when(subsetService.getData(any(DatabaseDto.class), anyString())) + .thenReturn(mock); + when(httpServletRequest.getMethod()) + .thenReturn("GET"); + + /* test */ + assertThrows(NotAllowedException.class, () -> { + viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, null); + }); + } + @Test @WithMockUser(username = USER_1_USERNAME, authorities = {"view-database-view-data"}) public void getData_privateHead_succeeds() throws RemoteUnavailableException, ViewNotFoundException, @@ -304,12 +335,14 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_3_ID)) - .thenReturn(VIEW_3_PRIVILEGED_DTO); + .thenReturn(VIEW_3_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(credentialService.getAccess(DATABASE_1_ID, USER_1_ID)) .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO); when(httpServletRequest.getMethod()) .thenReturn("HEAD"); - when(viewService.count(eq(VIEW_3_PRIVILEGED_DTO), any(Instant.class))) + when(viewService.count(any(DatabaseDto.class), eq(VIEW_3_DTO), any(Instant.class))) .thenReturn(VIEW_3_DATA_COUNT); /* test */ @@ -331,7 +364,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); when(httpServletRequest.getMethod()) .thenReturn("GET"); doThrow(NotAllowedException.class) @@ -367,7 +400,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_4_ID); @@ -385,7 +418,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_4_ID); @@ -419,7 +452,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* mock */ when(credentialService.getView(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); doThrow(NotAllowedException.class) .when(credentialService) .getAccess(DATABASE_1_ID, USER_4_ID); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java index 664e504248bb2136206817f8fabc8964fae0fdaf..d07123796c9413d8dfbaf0f9e1d80e34659b83ef 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/gateway/MetadataServiceGatewayUnitTest.java @@ -51,24 +51,14 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { @Test public void getTableById_succeeds() throws TableNotFoundException, RemoteUnavailableException, MetadataServiceException { - final HttpHeaders headers = new HttpHeaders(); - headers.set("X-Username", CONTAINER_1_PRIVILEGED_USERNAME); - headers.set("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD); - headers.set("X-Jdbc-Method", IMAGE_1_JDBC); /* mock */ when(internalRestTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(TableDto.class))) .thenReturn(ResponseEntity.status(HttpStatus.OK) - .headers(headers) - .body(TABLE_1_PRIVILEGED_DTO)); + .body(TABLE_1_DTO)); /* test */ final TableDto response = metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID); - assertEquals(IMAGE_1_JDBC, response.getDatabase().getContainer().getImage().getJdbcMethod()); - assertEquals(CONTAINER_1_HOST, response.getDatabase().getContainer().getHost()); - assertEquals(CONTAINER_1_PORT, response.getDatabase().getContainer().getPort()); - assertEquals(CONTAINER_1_PRIVILEGED_USERNAME, response.getDatabase().getContainer().getUsername()); - assertEquals(CONTAINER_1_PRIVILEGED_PASSWORD, response.getDatabase().getContainer().getPassword()); assertEquals(TABLE_1_INTERNAL_NAME, response.getInternalName()); } @@ -106,7 +96,7 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { /* mock */ when(internalRestTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(TableDto.class))) .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT) - .body(TABLE_1_PRIVILEGED_DTO)); + .body(TABLE_1_DTO)); /* test */ assertThrows(MetadataServiceException.class, () -> { @@ -114,27 +104,6 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { }); } - @Test - public void getTableById_headerMissing_fails() { - final List<String> customHeaders = List.of("X-Username", "X-Password"); - - for (int i = 0; i < customHeaders.size(); i++) { - final HttpHeaders headers = new HttpHeaders(); - for (int j = 0; j < i; j++) { - headers.add(customHeaders.get(j), ""); - } - /* mock */ - when(internalRestTemplate.exchange(anyString(), eq(HttpMethod.GET), eq(HttpEntity.EMPTY), eq(TableDto.class))) - .thenReturn(ResponseEntity.status(HttpStatus.OK) - .headers(headers) - .body(TABLE_1_PRIVILEGED_DTO)); - /* test */ - assertThrows(MetadataServiceException.class, () -> { - metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID); - }); - } - } - @Test public void getTableById_emptyBody_fails() { final HttpHeaders headers = new HttpHeaders(); @@ -354,16 +323,11 @@ public class MetadataServiceGatewayUnitTest extends AbstractUnitTest { @Test public void getViewById_succeeds() throws RemoteUnavailableException, ViewNotFoundException, MetadataServiceException { - final HttpHeaders headers = new HttpHeaders(); - headers.set("X-Username", CONTAINER_1_PRIVILEGED_USERNAME); - headers.set("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD); - headers.set("X-Jdbc-Method", IMAGE_1_JDBC); /* mock */ when(internalRestTemplate.exchange(anyString(), eq(HttpMethod.GET), any(HttpEntity.class), eq(ViewDto.class))) .thenReturn(ResponseEntity.ok() - .headers(headers) - .body(VIEW_1_PRIVILEGED_DTO)); + .body(VIEW_1_DTO)); /* test */ final ViewDto response = metadataServiceGateway.getViewById(CONTAINER_1_ID, VIEW_1_ID); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerIntegrationTest.java index bca5e1141082e320fe1bef132335fea7e30b7be3..bf63189bf22e08a6c6c46df6623ef1a782345b98 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerIntegrationTest.java @@ -2,10 +2,11 @@ package at.tuwien.listener; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; +import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.exception.MetadataServiceException; import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.TableNotFoundException; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -42,7 +43,7 @@ import static org.mockito.Mockito.when; public class DefaultListenerIntegrationTest extends AbstractUnitTest { @MockBean - private CredentialService credentialService; + private CacheService credentialService; @Autowired private DefaultListener defaultListener; @@ -58,17 +59,19 @@ public class DefaultListenerIntegrationTest extends AbstractUnitTest { genesis(); /* database */ MariaDbConfig.dropAllDatabases(CONTAINER_1_PRIVILEGED_DTO); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test public void onMessage_succeeds(CapturedOutput output) throws TableNotFoundException, RemoteUnavailableException, - MetadataServiceException { + MetadataServiceException, DatabaseNotFoundException { final Message request = buildMessage("dbrepo." + DATABASE_1_ID + "." + TABLE_1_ID, "{\"id\":4,\"date\":\"2023-10-03\",\"mintemp\":15.0,\"rainfall\":0.2}", new HashMap<>()); /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); /* test */ defaultListener.onMessage(request); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerUnitTest.java index 120f5936808a7bafab30f28a7b21149077a7954f..686a134dc56f5c118a5e25b2cb0150eb05ac47fd 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/listener/DefaultListenerUnitTest.java @@ -2,10 +2,11 @@ package at.tuwien.listener; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; +import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.exception.MetadataServiceException; import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.TableNotFoundException; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -38,7 +39,7 @@ import static org.mockito.Mockito.when; public class DefaultListenerUnitTest extends AbstractUnitTest { @MockBean - private CredentialService credentialService; + private CacheService credentialService; @Autowired private DefaultListener defaultListener; @@ -54,7 +55,7 @@ public class DefaultListenerUnitTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropAllDatabases(CONTAINER_1_PRIVILEGED_DTO); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test @@ -77,12 +78,14 @@ public class DefaultListenerUnitTest extends AbstractUnitTest { @Test public void onMessage_messageMalformed_fails(CapturedOutput output) throws TableNotFoundException, - RemoteUnavailableException, MetadataServiceException { + RemoteUnavailableException, MetadataServiceException, DatabaseNotFoundException { final Message request = buildMessage(TABLE_1_ROUTING_KEY, "{,}", new HashMap<>()); /* mock */ when(credentialService.getTable(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); + when(credentialService.getDatabase(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); /* test */ defaultListener.onMessage(request); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java index dacc80acceec164a6c61f50ec3d9a069b5807aad..ae03fdbf68cefc1db05455d0ec228ea00be1c12f 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java @@ -2,6 +2,7 @@ package at.tuwien.mvc; import at.tuwien.api.database.query.ExecuteStatementDto; import at.tuwien.api.database.query.ImportDto; +import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryPersistDto; import at.tuwien.api.database.table.TupleDeleteDto; import at.tuwien.api.database.table.TupleDto; @@ -110,7 +111,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest { /* ignore */ } try { - subsetEndpoint.create(DATABASE_1_ID, ExecuteStatementDto.builder().statement(QUERY_5_STATEMENT).build(), USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L); + subsetEndpoint.create(DATABASE_1_ID, QUERY_1_SUBSET_DTO, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L); } catch (Exception e) { /* ignore */ } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java index 2c174e0a3da88a30e2e8ed8d739cf0200fd5a237..abcfd4a175b2cd62cc8fef73c4f9627bc2077d62 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/AccessServiceIntegrationTest.java @@ -45,7 +45,7 @@ public class AccessServiceIntegrationTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/CredentialServiceUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/CredentialServiceUnitTest.java index 764dd92af3be5ea185b7e7ef319fde19a5e794af..95121ad704006cd814cf4962597e6382bc72b284 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/CredentialServiceUnitTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/CredentialServiceUnitTest.java @@ -8,7 +8,7 @@ import at.tuwien.api.database.table.TableDto; import at.tuwien.api.user.UserDto; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; -import at.tuwien.service.impl.CredentialServiceImpl; +import at.tuwien.service.impl.CacheServiceImpl; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.BeforeEach; @@ -30,7 +30,7 @@ import static org.mockito.Mockito.when; public class CredentialServiceUnitTest extends AbstractUnitTest { @Autowired - private CredentialServiceImpl credentialService; + private CacheServiceImpl credentialService; @MockBean private MetadataServiceGateway metadataServiceGateway; @@ -48,7 +48,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_1_DTO); /* test */ final DatabaseDto response = credentialService.getDatabase(DATABASE_1_ID); @@ -62,7 +62,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_1_ID)) - .thenReturn(DATABASE_1_PRIVILEGED_DTO) + .thenReturn(DATABASE_1_DTO) .thenThrow(RuntimeException.class) /* should never be thrown */; credentialService.getDatabase(DATABASE_1_ID); @@ -78,8 +78,8 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getDatabaseById(DATABASE_1_ID)) - .thenReturn(DATABASE_2_PRIVILEGED_DTO) /* needs to be different id for test case */ - .thenReturn(DATABASE_1_PRIVILEGED_DTO); + .thenReturn(DATABASE_2_DTO) /* needs to be different id for test case */ + .thenReturn(DATABASE_1_DTO); /* pre-condition */ final DatabaseDto tmp = credentialService.getDatabase(DATABASE_1_ID); @@ -98,7 +98,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getContainerById(CONTAINER_1_ID)) - .thenReturn(CONTAINER_1_PRIVILEGED_DTO); + .thenReturn(CONTAINER_1_DTO); /* test */ final ContainerDto response = credentialService.getContainer(CONTAINER_1_ID); @@ -128,8 +128,8 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getContainerById(CONTAINER_1_ID)) - .thenReturn(CONTAINER_2_PRIVILEGED_DTO) /* needs to be different id for test case */ - .thenReturn(CONTAINER_1_PRIVILEGED_DTO); + .thenReturn(CONTAINER_2_DTO) /* needs to be different id for test case */ + .thenReturn(CONTAINER_1_DTO); /* pre-condition */ final ContainerDto tmp = credentialService.getContainer(CONTAINER_1_ID); @@ -251,7 +251,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); /* test */ final TableDto response = credentialService.getTable(DATABASE_1_ID, TABLE_1_ID); @@ -265,7 +265,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO) + .thenReturn(TABLE_1_DTO) .thenThrow(RuntimeException.class) /* should never be thrown */; credentialService.getTable(DATABASE_1_ID, TABLE_1_ID); @@ -281,8 +281,8 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_2_PRIVILEGED_DTO) /* needs to be different id for test case */ - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_2_DTO) /* needs to be different id for test case */ + .thenReturn(TABLE_1_DTO); /* pre-condition */ final TableDto tmp = credentialService.getTable(DATABASE_1_ID, TABLE_1_ID); @@ -301,7 +301,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getViewById(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_1_DTO); /* test */ final ViewDto response = credentialService.getView(DATABASE_1_ID, VIEW_1_ID); @@ -314,7 +314,7 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getViewById(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_1_PRIVILEGED_DTO) + .thenReturn(VIEW_1_DTO) .thenThrow(RuntimeException.class) /* should never be thrown */; credentialService.getView(DATABASE_1_ID, VIEW_1_ID); @@ -330,8 +330,8 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { /* mock */ when(metadataServiceGateway.getViewById(DATABASE_1_ID, VIEW_1_ID)) - .thenReturn(VIEW_2_PRIVILEGED_DTO) /* needs to be different id for test case */ - .thenReturn(VIEW_1_PRIVILEGED_DTO); + .thenReturn(VIEW_2_DTO) /* needs to be different id for test case */ + .thenReturn(VIEW_1_DTO); /* pre-condition */ final ViewDto tmp = credentialService.getView(DATABASE_1_ID, VIEW_1_ID); @@ -344,26 +344,4 @@ public class CredentialServiceUnitTest extends AbstractUnitTest { assertEquals(VIEW_1_ID, response.getId()); } - @Test - public void invalidateAccess_succeeds() throws NotAllowedException, RemoteUnavailableException, - MetadataServiceException { - - /* mock */ - when(metadataServiceGateway.getAccess(DATABASE_1_ID, USER_1_ID)) - .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO) - .thenThrow(RuntimeException.class); - - /* pre-condition */ - final DatabaseAccessDto response = credentialService.getAccess(DATABASE_1_ID, USER_1_ID); - assertNotNull(response); - - /* test */ - credentialService.invalidateAccess(DATABASE_1_ID); - - /* post-condition */ - assertThrows(RuntimeException.class, () -> { - credentialService.getAccess(DATABASE_1_ID, USER_1_ID); - }); - } - } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java index 5d0a95ed89cb8689106e34ec69449b8383667df1..40fdb982ab062bb502597e899ac04caec496b564 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java @@ -63,9 +63,9 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_2_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_2_DTO); + MariaDbConfig.createInitDatabase(DATABASE_2_PRIVILEGED_DTO); Thread.sleep(1000) /* wait for test container some more */; } @@ -73,7 +73,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { public void createView_succeeds() throws SQLException, ViewMalformedException { /* test */ - databaseService.createView(DATABASE_1_PRIVILEGED_DTO, VIEW_1_CREATE_DTO); + databaseService.createView(DATABASE_1_PRIVILEGED_DTO, VIEW_1_NAME, VIEW_1_QUERY); } @Test @@ -84,7 +84,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final ViewDto view0 = response.get(0); assertEquals("not_in_metadata_db2", view0.getName()); assertEquals("not_in_metadata_db2", view0.getInternalName()); - assertEquals(DATABASE_1_ID, view0.getVdbid()); + assertEquals(DATABASE_1_ID, view0.getDatabaseId()); assertEquals(USER_1_BRIEF_DTO, view0.getOwner()); assertFalse(view0.getIsInitialView()); assertEquals(DATABASE_1_PUBLIC, view0.getIsPublic()); @@ -149,7 +149,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto response = databaseService.inspectTable(DATABASE_1_PRIVILEGED_DTO, "not_in_metadata_db"); assertEquals("not_in_metadata_db", response.getInternalName()); assertEquals("not_in_metadata_db", response.getName()); - assertEquals(DATABASE_1_ID, response.getTdbid()); + assertEquals(DATABASE_1_ID, response.getDatabaseId()); assertTrue(response.getIsVersioned()); assertEquals(DATABASE_1_PUBLIC, response.getIsPublic()); final List<ColumnDto> columns = response.getColumns(); @@ -185,7 +185,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto response = databaseService.inspectTable(DATABASE_2_PRIVILEGED_DTO, "experiments"); assertEquals("experiments", response.getInternalName()); assertEquals("experiments", response.getName()); - assertEquals(DATABASE_2_ID, response.getTdbid()); + assertEquals(DATABASE_2_ID, response.getDatabaseId()); assertTrue(response.getIsVersioned()); assertEquals(DATABASE_2_PUBLIC, response.getIsPublic()); assertNotNull(response.getOwner()); @@ -218,7 +218,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto response = databaseService.inspectTable(DATABASE_1_PRIVILEGED_DTO, "weather_aus"); assertEquals("weather_aus", response.getInternalName()); assertEquals("weather_aus", response.getName()); - assertEquals(DATABASE_1_ID, response.getTdbid()); + assertEquals(DATABASE_1_ID, response.getDatabaseId()); assertTrue(response.getIsVersioned()); assertEquals(DATABASE_1_PUBLIC, response.getIsPublic()); assertNotNull(response.getOwner()); @@ -438,7 +438,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final ViewDto response = databaseService.inspectView(DATABASE_1_PRIVILEGED_DTO, "not_in_metadata_db2"); assertEquals("not_in_metadata_db2", response.getInternalName()); assertEquals("not_in_metadata_db2", response.getName()); - assertEquals(DATABASE_1_ID, response.getVdbid()); + assertEquals(DATABASE_1_ID, response.getDatabaseId()); assertEquals(USER_1_BRIEF_DTO, response.getOwner()); assertFalse(response.getIsInitialView()); assertEquals(DATABASE_1_PUBLIC, response.getIsPublic()); @@ -472,7 +472,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto table0 = response.get(0); Assertions.assertEquals("complex_foreign_keys", table0.getInternalName()); Assertions.assertEquals("complex_foreign_keys", table0.getName()); - Assertions.assertEquals(DATABASE_1_ID, table0.getTdbid()); + Assertions.assertEquals(DATABASE_1_ID, table0.getDatabaseId()); assertTrue(table0.getIsVersioned()); Assertions.assertEquals(DATABASE_1_PUBLIC, table0.getIsPublic()); final List<ColumnDto> columns0 = table0.getColumns(); @@ -519,7 +519,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto table1 = response.get(1); Assertions.assertEquals("complex_primary_key", table1.getInternalName()); Assertions.assertEquals("complex_primary_key", table1.getName()); - Assertions.assertEquals(DATABASE_1_ID, table1.getTdbid()); + Assertions.assertEquals(DATABASE_1_ID, table1.getDatabaseId()); assertTrue(table1.getIsVersioned()); Assertions.assertEquals(DATABASE_1_PUBLIC, table1.getIsPublic()); final List<ColumnDto> columns1 = table1.getColumns(); @@ -547,7 +547,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto table2 = response.get(2); Assertions.assertEquals("exotic_boolean", table2.getInternalName()); Assertions.assertEquals("exotic_boolean", table2.getName()); - Assertions.assertEquals(DATABASE_1_ID, table2.getTdbid()); + Assertions.assertEquals(DATABASE_1_ID, table2.getDatabaseId()); assertTrue(table2.getIsVersioned()); Assertions.assertEquals(DATABASE_1_PUBLIC, table2.getIsPublic()); final List<ColumnDto> columns2 = table2.getColumns(); @@ -568,7 +568,7 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest { final TableDto table3 = response.get(3); Assertions.assertEquals("not_in_metadata_db", table3.getInternalName()); Assertions.assertEquals("not_in_metadata_db", table3.getName()); - Assertions.assertEquals(DATABASE_1_ID, table3.getTdbid()); + Assertions.assertEquals(DATABASE_1_ID, table3.getDatabaseId()); assertTrue(table3.getIsVersioned()); Assertions.assertEquals(DATABASE_1_PUBLIC, table3.getIsPublic()); final List<ColumnDto> columns3 = table3.getColumns(); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java index 18b2dd8e01bc8d8e10f1de9bea9798846868bc6d..6996ecb9f49821b329471c6dd91dca0b4fcc74d5 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/QueueServiceIntegrationTest.java @@ -2,7 +2,7 @@ package at.tuwien.service; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; -import at.tuwien.exception.ContainerNotFoundException; +import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.exception.MetadataServiceException; import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.TableNotFoundException; @@ -53,12 +53,12 @@ public class QueueServiceIntegrationTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test - public void insert_succeeds() throws SQLException, RemoteUnavailableException, ContainerNotFoundException, - TableNotFoundException, MetadataServiceException { + public void insert_succeeds() throws SQLException, RemoteUnavailableException, TableNotFoundException, + MetadataServiceException, DatabaseNotFoundException { final Map<String, Object> request = new HashMap<>() {{ put("id", 4L); put("date", "2023-10-03"); @@ -68,29 +68,31 @@ public class QueueServiceIntegrationTest extends AbstractUnitTest { }}; /* mock */ - when(metadataServiceGateway.getContainerById(CONTAINER_1_ID)) - .thenReturn(CONTAINER_1_PRIVILEGED_DTO); + when(metadataServiceGateway.getDatabaseById(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); /* test */ - queueService.insert(TABLE_1_PRIVILEGED_DTO, request); + queueService.insert(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); } @Test public void insert_onlyMandatoryFields_succeeds() throws SQLException, RemoteUnavailableException, - TableNotFoundException, MetadataServiceException { + TableNotFoundException, MetadataServiceException, DatabaseNotFoundException { final Map<String, Object> request = new HashMap<>() {{ put("id", 5L); put("date", "2023-10-04"); }}; /* mock */ + when(metadataServiceGateway.getDatabaseById(DATABASE_1_ID)) + .thenReturn(DATABASE_1_PRIVILEGED_DTO); when(metadataServiceGateway.getTableById(DATABASE_1_ID, TABLE_1_ID)) - .thenReturn(TABLE_1_PRIVILEGED_DTO); + .thenReturn(TABLE_1_DTO); /* test */ - queueService.insert(TABLE_1_PRIVILEGED_DTO, request); + queueService.insert(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); } } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java index cd92d5579c0f66297c10661ad3c0a2a0201141f0..d5bfaa1bbb56ace796babe4e9cb17d0098298bfe 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java @@ -8,6 +8,8 @@ import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.test.AbstractUnitTest; import lombok.extern.log4j.Log4j2; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -20,6 +22,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.sql.SQLException; +import java.time.Instant; +import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -33,7 +37,7 @@ import static org.mockito.Mockito.when; public class SubsetServiceIntegrationTest extends AbstractUnitTest { @Autowired - private SubsetService queryService; + private SubsetService subsetService; @MockBean private MetadataServiceGateway metadataServiceGateway; @@ -46,7 +50,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test @@ -112,7 +116,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { /* test */ persist_generic(queryId2, List.of(IDENTIFIER_5_BRIEF_DTO), true); - final QueryDto response = queryService.findById(DATABASE_1_PRIVILEGED_DTO, queryId2); + final QueryDto response = subsetService.findById(DATABASE_1_PRIVILEGED_DTO, queryId2); assertEquals(queryId2, response.getId()); assertTrue(response.getIsPersisted()); } @@ -129,11 +133,109 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { /* test */ persist_generic(queryId1, List.of(IDENTIFIER_2_BRIEF_DTO), false); - final QueryDto response = queryService.findById(DATABASE_1_PRIVILEGED_DTO, queryId1); + final QueryDto response = subsetService.findById(DATABASE_1_PRIVILEGED_DTO, queryId1); assertEquals(queryId1, response.getId()); assertFalse(response.getIsPersisted()); } + @Test + public void getData_succeeds() throws QueryMalformedException, TableNotFoundException { + final List<List<String>> expected = List.of( + List.of("1", "2008-12-01", "Albury", "13.4", "0.6"), + List.of("2", "2008-12-02", "Albury", "7.4", "0.0"), + List.of("3", "2008-12-03", "Albury", "12.9", "0.0")); + + + /* test */ + final Dataset<Row> response = subsetService.getData(DATABASE_1_PRIVILEGED_DTO, QUERY_1_STATEMENT); + assertNotNull(response); + final List<List<String>> mapped = response.collectAsList() + .stream() + .map(row -> { + final List<String> map = new LinkedList<>(); + for (int i = 0; i < response.columns().length; i++) { + map.add(row.get(i) != null ? String.valueOf(row.get(i)) : ""); + } + return map; + }) + .toList(); + assertEquals(expected, mapped); + } + + @Test + public void getData_notFound_fails() { + + /* test */ + assertThrows(TableNotFoundException.class, () -> { + subsetService.getData(DATABASE_1_PRIVILEGED_DTO, "SELECT 1 FROM i_do_not_exist"); + }); + } + + @Test + public void reExecuteCount_succeeds() throws SQLException, QueryMalformedException { + + /* test */ + final Long response = subsetService.reExecuteCount(DATABASE_1_PRIVILEGED_DTO, QUERY_1_DTO); + assertNotNull(response); + } + + @Test + public void reExecuteCount_malformed_fails() { + final QueryDto request = QueryDto.builder() + .execution(Instant.now()) + .databaseId(DATABASE_1_ID) + .query("SELECT") // <<< + .build(); + + /* test */ + assertThrows(QueryMalformedException.class, () -> { + subsetService.reExecuteCount(DATABASE_1_PRIVILEGED_DTO, request); + }); + } + + @Test + public void executeCountNonPersistent_succeeds() throws SQLException, QueryMalformedException { + + /* test */ + final Long response = subsetService.executeCountNonPersistent(DATABASE_1_PRIVILEGED_DTO, QUERY_1_STATEMENT, QUERY_1_CREATED); + assertNotNull(response); + } + + @Test + public void executeCountNonPersistent_malformed_fails() { + + /* test */ + assertThrows(QueryMalformedException.class, () -> { + subsetService.executeCountNonPersistent(DATABASE_1_PRIVILEGED_DTO, "SELECT", QUERY_1_CREATED); + }); + } + + @Test + public void executeCountNonPersistent_illegalQuery_fails() { + + /* test */ + assertThrows(QueryMalformedException.class, () -> { + subsetService.executeCountNonPersistent(DATABASE_1_PRIVILEGED_DTO, "DROP DATABASE `weather`", QUERY_1_CREATED); + }); + } + + @Test + public void storeQuery_succeeds() throws SQLException, QueryStoreInsertException, ViewMalformedException { + + /* test */ + final UUID response = subsetService.storeQuery(DATABASE_1_PRIVILEGED_DTO, QUERY_1_STATEMENT, QUERY_1_CREATED, USER_1_ID); + assertNotNull(response); + } + + @Test + public void storeQuery_fails() { + + /* test */ + assertThrows(QueryStoreInsertException.class, () -> { + subsetService.storeQuery(DATABASE_1_PRIVILEGED_DTO, "DROP DATABASE `weather`", QUERY_1_CREATED, USER_1_ID); + }); + } + protected void findById_generic(UUID queryId) throws RemoteUnavailableException, SQLException, UserNotFoundException, QueryNotFoundException, MetadataServiceException, DatabaseNotFoundException, InterruptedException { @@ -148,7 +250,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { .thenReturn(USER_1_DTO); /* test */ - final QueryDto response = queryService.findById(DATABASE_1_PRIVILEGED_DTO, queryId); + final QueryDto response = subsetService.findById(DATABASE_1_PRIVILEGED_DTO, queryId); assertEquals(queryId, response.getId()); } @@ -166,7 +268,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { .thenReturn(List.of(IDENTIFIER_2_BRIEF_DTO, IDENTIFIER_5_BRIEF_DTO)); /* test */ - return queryService.findAll(DATABASE_1_PRIVILEGED_DTO, filterPersisted); + return subsetService.findAll(DATABASE_1_PRIVILEGED_DTO, filterPersisted); } protected void persist_generic(UUID queryId, List<IdentifierBriefDto> identifiers, Boolean persist) @@ -181,7 +283,7 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { .thenReturn(identifiers); /* test */ - queryService.persist(DATABASE_1_PRIVILEGED_DTO, queryId, persist); + subsetService.persist(DATABASE_1_PRIVILEGED_DTO, queryId, persist); } } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java index bd4eb4d04b2973d6751f43548a49312f2c240853..77e91361db1ddbc733251c0617ff658bd199ea7a 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationTest.java @@ -79,8 +79,8 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_2_INTERNALNAME); MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_3_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_3_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_3_PRIVILEGED_DTO); /* s3 */ if (s3Client.listBuckets().buckets().stream().noneMatch(b -> b.name().equals(s3Config.getS3Bucket()))) { s3Client.createBucket(CreateBucketRequest.builder() @@ -110,7 +110,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.updateTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.updateTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 1", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("1", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); // <<< @@ -137,7 +137,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.updateTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.updateTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 4", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("4", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); // <<< @@ -163,7 +163,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.updateTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.updateTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 1", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("1", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); // <<< @@ -189,7 +189,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.updateTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.updateTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 1", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("1", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); // <<< @@ -213,7 +213,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.createTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.createTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 4", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("4", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); @@ -240,7 +240,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(), RequestBody.fromFile(new File("src/test/resources/csv/keyboard.csv"))); /* test */ - tableService.createTuple(TABLE_8_PRIVILEGED_DTO, request); + tableService.createTuple(DATABASE_3_PRIVILEGED_DTO, TABLE_8_DTO, request); final List<Map<String, byte[]>> result = MariaDbConfig.selectQueryByteArr(DATABASE_3_PRIVILEGED_DTO, "SELECT raw FROM mfcc WHERE raw IS NOT NULL", Set.of("raw")); assertNotNull(result.get(0).get("raw")); assertArrayEquals(Files.toByteArray(new File("src/test/resources/csv/keyboard.csv")), result.get(0).get("raw")); @@ -261,7 +261,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.createTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.createTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id, `date`, location, mintemp, rainfall FROM weather_aus WHERE id = 4", Set.of("id", "date", "location", "mintemp", "rainfall")); assertEquals("4", result.get(0).get("id")); assertEquals("2023-10-03", result.get(0).get("date")); @@ -280,7 +280,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.deleteTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.deleteTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id FROM weather_aus WHERE id = 1", Set.of("id")); assertEquals(0, result.size()); } @@ -297,7 +297,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(); /* test */ - tableService.deleteTuple(TABLE_1_PRIVILEGED_DTO, request); + tableService.deleteTuple(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); final List<Map<String, String>> result = MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT id FROM weather_aus WHERE id = 1", Set.of("id")); assertEquals(0, result.size()); } @@ -307,7 +307,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { public void getStatistics_succeeds() throws TableMalformedException, SQLException, TableNotFoundException { /* test */ - final TableStatisticDto response = tableService.getStatistics(TABLE_2_PRIVILEGED_DTO); + final TableStatisticDto response = tableService.getStatistics(DATABASE_1_PRIVILEGED_DTO, TABLE_2_DTO); assertEquals(TABLE_2_COLUMNS.size(), response.getColumns().size()); log.trace("response rows: {}", response.getRows()); assertEquals(3L, response.getRows()); @@ -336,7 +336,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { public void delete_succeeds() throws SQLException, QueryMalformedException { /* test */ - tableService.delete(TABLE_1_PRIVILEGED_DTO); + tableService.delete(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO); } @Test @@ -347,7 +347,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* test */ assertThrows(QueryMalformedException.class, () -> { - tableService.delete(TABLE_5_PRIVILEGED_DTO); + tableService.delete(DATABASE_2_PRIVILEGED_DTO, TABLE_5_DTO); }); } @@ -355,7 +355,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { public void getCount_succeeds() throws SQLException, QueryMalformedException { /* test */ - final Long response = tableService.getCount(TABLE_1_PRIVILEGED_DTO, null); + final Long response = tableService.getCount(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, null); assertEquals(3, response); } @@ -363,7 +363,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { public void getCount_timestamp_succeeds() throws SQLException, QueryMalformedException { /* test */ - final Long response = tableService.getCount(TABLE_1_PRIVILEGED_DTO, Instant.ofEpochSecond(0)); + final Long response = tableService.getCount(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, Instant.ofEpochSecond(0)); assertEquals(0, response); } @@ -375,7 +375,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* test */ assertThrows(QueryMalformedException.class, () -> { - tableService.getCount(TABLE_5_PRIVILEGED_DTO, null); + tableService.getCount(DATABASE_2_PRIVILEGED_DTO, TABLE_5_DTO, null); }); } @@ -383,7 +383,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { public void history_succeeds() throws SQLException, TableNotFoundException { /* test */ - final List<TableHistoryDto> response = tableService.history(TABLE_1_PRIVILEGED_DTO, 1000L); + final List<TableHistoryDto> response = tableService.history(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, 1000L); assertEquals(1, response.size()); final TableHistoryDto history0 = response.get(0); assertNotNull(history0.getTimestamp()); @@ -399,7 +399,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* test */ assertThrows(TableNotFoundException.class, () -> { - tableService.history(TABLE_5_PRIVILEGED_DTO, null); + tableService.history(DATABASE_2_PRIVILEGED_DTO, TABLE_5_DTO, null); }); } @@ -421,7 +421,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { .build(), RequestBody.fromFile(new File("src/test/resources/csv/weather_aus.csv"))); /* test */ - tableService.importDataset(TABLE_1_PRIVILEGED_DTO, request); + tableService.importDataset(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); } @Test @@ -442,7 +442,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* test */ assertThrows(TableMalformedException.class, () -> { - tableService.importDataset(TABLE_1_PRIVILEGED_DTO, request); + tableService.importDataset(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); }); } @@ -464,7 +464,7 @@ public class TableServiceIntegrationTest extends AbstractUnitTest { /* test */ assertThrows(MalformedException.class, () -> { - tableService.importDataset(TABLE_1_PRIVILEGED_DTO, request); + tableService.importDataset(DATABASE_1_PRIVILEGED_DTO, TABLE_1_DTO, request); }); } diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java index 2edf7f5f28a2e607ba55eb38ca82547f112a60f5..5e99f4afbcf1c144ed3566d62a21dd0cd5f771e4 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java @@ -34,14 +34,14 @@ public class ViewServiceIntegrationTest extends AbstractUnitTest { genesis(); /* metadata database */ MariaDbConfig.dropDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_INTERNALNAME); - MariaDbConfig.createInitDatabase(CONTAINER_1_PRIVILEGED_DTO, DATABASE_1_PRIVILEGED_DTO); + MariaDbConfig.createInitDatabase(DATABASE_1_PRIVILEGED_DTO); } @Test public void delete_succeeds() throws SQLException, ViewMalformedException { /* test */ - viewService.delete(VIEW_1_PRIVILEGED_DTO); + viewService.delete(DATABASE_1_PRIVILEGED_DTO, VIEW_1_DTO); } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java index 3140f77cb585ef3ba02937b514ed3a1cd36631da..1e9d1c4bf0653758f4334f44d5c665610b7fc0fa 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java @@ -13,6 +13,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; @@ -52,13 +53,13 @@ public class AuthTokenFilter extends OncePerRequestFilter { filterChain.doFilter(request, response); } - public UserDetails verifyJwt(String token) throws ServletException { + public UserDetails verifyJwt(String token) throws BadCredentialsException { final KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { log.error("Failed to find RSA algorithm"); - throw new ServletException("Failed to find RSA algorithm", e); + throw new BadCredentialsException("Failed to find RSA algorithm", e); } final X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey)); final RSAPublicKey pubKey; @@ -66,7 +67,7 @@ public class AuthTokenFilter extends OncePerRequestFilter { pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509); } catch (InvalidKeySpecException e) { log.error("Provided public key is invalid"); - throw new ServletException("Provided public key is invalid", e); + throw new BadCredentialsException("Provided public key is invalid", e); } final Algorithm algorithm = Algorithm.RSA256(pubKey, null); final Verification verification = JWT.require(algorithm); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java index 80fdd15f1daff7625508eb8d46d9b54332a5150f..f7f51c0b0d5eab1d06d5e83cc93256cf5211c911 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java @@ -1,13 +1,10 @@ package at.tuwien.auth; import at.tuwien.api.keycloak.TokenDto; -import at.tuwien.exception.*; import at.tuwien.gateway.KeycloakGateway; -import jakarta.servlet.ServletException; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -29,13 +26,8 @@ public class BasicAuthenticationProvider implements AuthenticationManager { @Override public Authentication authenticate(Authentication auth) throws AuthenticationException { - try { - final TokenDto tokenDto = keycloakGateway.obtainUserToken(auth.getName(), auth.getCredentials().toString()); - final UserDetails userDetails = authTokenFilter.verifyJwt(tokenDto.getAccessToken()); - return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - } catch (ServletException | CredentialsInvalidException | AccountNotSetupException | - AuthServiceConnectionException e) { - throw new BadCredentialsException("Failed to authenticate with authentication service", e); - } + final TokenDto tokenDto = keycloakGateway.obtainUserToken(auth.getName(), auth.getCredentials().toString()); + final UserDetails userDetails = authTokenFilter.verifyJwt(tokenDto.getAccessToken()); + return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java index 20955bcdb36912e3f8dd4ed695a4e688f1177ccf..b0edc929ed0097ce94e65153707dc47406f0f3c9 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/auth/InternalRequestInterceptor.java @@ -2,7 +2,6 @@ package at.tuwien.auth; import at.tuwien.api.keycloak.TokenDto; import at.tuwien.config.GatewayConfig; -import at.tuwien.exception.*; import at.tuwien.gateway.KeycloakGateway; import lombok.extern.log4j.Log4j2; import org.springframework.http.HttpHeaders; @@ -31,15 +30,10 @@ public class InternalRequestInterceptor implements ClientHttpRequestInterceptor throws IOException { final HttpHeaders headers = request.getHeaders(); headers.setAccept(List.of(MediaType.APPLICATION_JSON)); - try { - final TokenDto token = keycloakGateway.obtainUserToken(gatewayConfig.getSystemUsername(), - gatewayConfig.getSystemPassword()); - headers.setBearerAuth(token.getAccessToken()); - log.trace("set bearer token for internal user: {}", gatewayConfig.getSystemUsername()); - } catch (AuthServiceConnectionException | CredentialsInvalidException | AccountNotSetupException e) { - log.error("Failed to obtain token for internal user: {}", gatewayConfig.getSystemUsername()); - throw new IOException("Failed to obtain token for internal user", e); - } + final TokenDto token = keycloakGateway.obtainUserToken(gatewayConfig.getSystemUsername(), + gatewayConfig.getSystemPassword()); + headers.setBearerAuth(token.getAccessToken()); + log.trace("set bearer token for internal user: {}", gatewayConfig.getSystemUsername()); return execution.execute(request, body); } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java index c511f2b511ff3cd66d52f63a55ca8ca73ce2a6c9..1a92faf86f39c5568b9fd927499a61874aacc09c 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -5,6 +5,7 @@ import at.tuwien.gateway.KeycloakGateway; import lombok.Getter; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java b/dbrepo-data-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java index cc6960ba39be294a61e059f3a3f45ecfc8e820fd..57183b87672a078c1462ad25b9d3504b4ffe38b9 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/config/KeycloakConfig.java @@ -1,8 +1,11 @@ package at.tuwien.config; import lombok.Getter; +import org.keycloak.admin.client.Keycloak; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; @Getter @Configuration @@ -22,4 +25,11 @@ public class KeycloakConfig { @Value("${dbrepo.keycloak.clientSecret}") private String keycloakClientSecret; + + private final String realm = "dbrepo"; + + @Bean + public Keycloak keycloak() { + return Keycloak.getInstance(keycloakEndpoint, "master", keycloakUsername, keycloakPassword, "admin-cli"); + } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java index 9e6a5f56bda37fc1b3d9af9fca8158a5fcce27f7..21fbf674db6fbee0890528c2cb465eab53bba1c2 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java @@ -4,10 +4,11 @@ import at.tuwien.api.keycloak.TokenDto; import at.tuwien.exception.AccountNotSetupException; import at.tuwien.exception.AuthServiceConnectionException; import at.tuwien.exception.CredentialsInvalidException; +import at.tuwien.exception.NotAllowedException; +import org.springframework.security.authentication.BadCredentialsException; public interface KeycloakGateway { - TokenDto obtainUserToken(String username, String password) throws AuthServiceConnectionException, - CredentialsInvalidException, AccountNotSetupException; + TokenDto obtainUserToken(String username, String password) throws BadCredentialsException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java index 1e235de4c63d883f2807c67e94480105750f5019..1e14a4b4ceec8e3738f7796b4867fb1dd455ea8d 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java @@ -2,67 +2,47 @@ package at.tuwien.gateway.impl; import at.tuwien.api.keycloak.TokenDto; import at.tuwien.config.KeycloakConfig; -import at.tuwien.exception.AccountNotSetupException; -import at.tuwien.exception.AuthServiceConnectionException; -import at.tuwien.exception.CredentialsInvalidException; import at.tuwien.gateway.KeycloakGateway; +import at.tuwien.mapper.MetadataMapper; +import jakarta.ws.rs.NotAuthorizedException; import lombok.extern.log4j.Log4j2; +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.KeycloakBuilder; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.*; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.RestTemplate; @Log4j2 @Service public class KeycloakGatewayImpl implements KeycloakGateway { private final KeycloakConfig keycloakConfig; + private final MetadataMapper metadataMapper; @Autowired - public KeycloakGatewayImpl(KeycloakConfig keycloakConfig) { + public KeycloakGatewayImpl(KeycloakConfig keycloakConfig, MetadataMapper metadataMapper) { this.keycloakConfig = keycloakConfig; + this.metadataMapper = metadataMapper; } @Override - public TokenDto obtainUserToken(String username, String password) throws AuthServiceConnectionException, - CredentialsInvalidException, AccountNotSetupException { - final HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - final MultiValueMap<String, String> payload = new LinkedMultiValueMap<>(); - payload.add("username", username); - payload.add("password", password); - payload.add("grant_type", "password"); - payload.add("scope", "openid roles"); - payload.add("client_id", keycloakConfig.getKeycloakClient()); - payload.add("client_secret", keycloakConfig.getKeycloakClientSecret()); - final String url = keycloakConfig.getKeycloakEndpoint() + "/realms/dbrepo/protocol/openid-connect/token"; - log.trace("request user token from url: {}", url); - final ResponseEntity<TokenDto> response; - try { - response = new RestTemplate() - .exchange(url, HttpMethod.POST, new HttpEntity<>(payload, headers), TokenDto.class); - } catch (HttpServerErrorException e) { + public TokenDto obtainUserToken(String username, String password) throws BadCredentialsException { + try (Keycloak userKeycloak = KeycloakBuilder.builder() + .serverUrl(keycloakConfig.getKeycloakEndpoint()) + .realm(keycloakConfig.getRealm()) + .grantType(OAuth2Constants.PASSWORD) + .clientId(keycloakConfig.getKeycloakClient()) + .clientSecret(keycloakConfig.getKeycloakClientSecret()) + .username(username) + .password(password) + .build()) { + return metadataMapper.accessTokenResponseToTokenDto(userKeycloak.tokenManager() + .getAccessToken()); + } catch (NotAuthorizedException e) { log.error("Failed to obtain user token: {}", e.getMessage()); - throw new AuthServiceConnectionException("Failed to obtain user token: " + e.getMessage(), e); - } catch (HttpClientErrorException.BadRequest e) { - if (e.getResponseBodyAsByteArray() != null && e.getResponseBodyAsByteArray().length > 0) { - final String error = e.getResponseBodyAsString(); - if (error != null && error.contains("invalid_grant")) { - log.error("Failed to obtain user token: {}", error); - throw new AccountNotSetupException("Failed to obtain user token: " + error, e); - } - } - log.error("Failed to obtain user token: bad request"); - throw new CredentialsInvalidException("Bad request", e); - } catch (HttpClientErrorException.Unauthorized e) { - log.error("Failed to obtain user token: invalid credentials"); - throw new CredentialsInvalidException("Invalid credentials: " + e.getMessage(), e); + throw new BadCredentialsException("Failed to obtain user token", e); } - return response.getBody(); } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java index d90250f0287806b8c8a659268eb0c81ff1a4bd2f..cd8cfff2da2aa255d7137eb43ed099ec778812cc 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/gateway/impl/MetadataServiceGatewayImpl.java @@ -139,21 +139,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find table with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find table: service responded unsuccessful: " + response.getStatusCode()); } - final List<String> expectedHeaders = List.of("X-Username", "X-Password", "X-Jdbc-Method"); - if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { - log.error("Failed to find all table headers"); - log.debug("expected headers: {}", expectedHeaders); - log.debug("found headers: {}", response.getHeaders().keySet()); - throw new MetadataServiceException("Failed to find all table headers"); - } if (response.getBody() == null) { log.error("Failed to find table with id {}: body is empty", id); throw new MetadataServiceException("Failed to find table with id " + id + ": body is empty"); } final TableDto table = metadataMapper.tableDtoToTableDto(response.getBody()); - table.getDatabase().getContainer().setUsername(response.getHeaders().get("X-Username").get(0)); - table.getDatabase().getContainer().setPassword(response.getHeaders().get("X-Password").get(0)); - table.getDatabase().getContainer().getImage().setJdbcMethod(response.getHeaders().get("X-Jdbc-Method").get(0)); table.setLastRetrieved(Instant.now()); return table; } @@ -177,21 +167,11 @@ public class MetadataServiceGatewayImpl implements MetadataServiceGateway { log.error("Failed to find view with id {}: service responded unsuccessful: {}", id, response.getStatusCode()); throw new MetadataServiceException("Failed to find view: service responded unsuccessful: " + response.getStatusCode()); } - final List<String> expectedHeaders = List.of("X-Username", "X-Password", "X-Jdbc-Method"); - if (!response.getHeaders().keySet().containsAll(expectedHeaders)) { - log.error("Failed to find all view headers"); - log.debug("expected headers: {}", expectedHeaders); - log.debug("found headers: {}", response.getHeaders().keySet()); - throw new MetadataServiceException("Failed to find all view headers"); - } if (response.getBody() == null) { log.error("Failed to find view with id {}: body is empty", id); throw new MetadataServiceException("Failed to find view with id " + id + ": body is empty"); } final ViewDto view = metadataMapper.viewDtoToViewDto(response.getBody()); - view.getDatabase().getContainer().setUsername(response.getHeaders().get("X-Username").get(0)); - view.getDatabase().getContainer().setPassword(response.getHeaders().get("X-Password").get(0)); - view.getDatabase().getContainer().getImage().setJdbcMethod(response.getHeaders().get("X-Jdbc-Method").get(0)); view.setLastRetrieved(Instant.now()); return view; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/listener/DefaultListener.java b/dbrepo-data-service/services/src/main/java/at/tuwien/listener/DefaultListener.java index 336a48311739f15ec95c3546ebbeaee4130a8cde..929ede0a8f3e7ee1467a2def289c836d9823f531 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/listener/DefaultListener.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/listener/DefaultListener.java @@ -1,10 +1,12 @@ package at.tuwien.listener; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.table.TableDto; +import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.exception.MetadataServiceException; import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.TableNotFoundException; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import at.tuwien.service.QueueService; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -27,15 +29,15 @@ import java.util.UUID; @Component public class DefaultListener implements MessageListener { + private final CacheService cacheService; private final ObjectMapper objectMapper; private final QueueService queueService; - private final CredentialService credentialService; @Autowired - public DefaultListener(ObjectMapper objectMapper, QueueService queueService, CredentialService credentialService) { + public DefaultListener(CacheService cacheService, ObjectMapper objectMapper, QueueService queueService) { + this.cacheService = cacheService; this.objectMapper = objectMapper; this.queueService = queueService; - this.credentialService = credentialService; } @Override @@ -59,15 +61,18 @@ public class DefaultListener implements MessageListener { log.trace("received message for table with id {} of database id {}: {} bytes", tableId, databaseId, message.getMessageProperties().getContentLength()); final Map<String, Object> body; try { - final TableDto table = credentialService.getTable(databaseId, tableId); + final DatabaseDto database = cacheService.getDatabase(databaseId); + final TableDto table = cacheService.getTable(databaseId, tableId); body = objectMapper.readValue(message.getBody(), typeRef); - queueService.insert(table, body); + queueService.insert(database, table, body); } catch (IOException e) { log.error("Failed to read object: {}", e.getMessage()); } catch (SQLException | RemoteUnavailableException e) { log.error("Failed to insert tuple: {}", e.getMessage()); } catch (TableNotFoundException | MetadataServiceException e) { log.error("Failed to find table: {}", e.getMessage()); + } catch (DatabaseNotFoundException e) { + log.error("Failed to find database: {}", e.getMessage()); } } } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java index df65225a3f63e2e9446ab9793ab9a8ce05af0b0f..9692b48b9e171fbf87e534612190e8c4f1ae2bd8 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java @@ -48,9 +48,6 @@ public interface DataMapper { ColumnBriefDto columnDtoToColumnBriefDto(ColumnDto data); /* redundant */ - @Mappings({ - @Mapping(target = "databaseId", source = "tdbid") - }) TableBriefDto tableDtoToTableBriefDto(TableDto data); /* redundant */ @@ -58,9 +55,11 @@ public interface DataMapper { ForeignKeyBriefDto foreignKeyDtoToForeignKeyBriefDto(ForeignKeyDto data); - default String rabbitMqTupleToInsertOrUpdateQuery(TableDto table, Map<String, Object> data) { + default String rabbitMqTupleToInsertOrUpdateQuery(String databaseName, TableDto table, Map<String, Object> data) { /* parameterized query for prepared statement */ final StringBuilder statement = new StringBuilder("INSERT INTO `") + .append(databaseName) + .append("`.`") .append(table.getInternalName()) .append("` (") .append(data.keySet() @@ -89,7 +88,7 @@ public interface DataMapper { return ViewDto.builder() .name(resultSet.getString(1)) .internalName(resultSet.getString(1)) - .vdbid(database.getId()) + .databaseId(database.getId()) .isInitialView(false) .isPublic(database.getIsPublic()) .isSchemaPublic(database.getIsSchemaPublic()) @@ -129,7 +128,7 @@ public interface DataMapper { .name(resultSet.getString(10)) .internalName(resultSet.getString(10)) .tableId(table.getId()) - .databaseId(table.getTdbid()) + .databaseId(table.getDatabaseId()) .description(resultSet.getString(11)) .build(); final String dataType = resultSet.getString(8); @@ -179,7 +178,7 @@ public interface DataMapper { .d(resultSet.getString(7) != null ? resultSet.getLong(7) : null) .name(resultSet.getString(10)) .internalName(resultSet.getString(10)) - .databaseId(view.getVdbid()) + .databaseId(view.getDatabaseId()) .build(); /* fix boolean and set size for others */ if (resultSet.getString(8).equalsIgnoreCase("tinyint(1)")) { @@ -273,12 +272,12 @@ public interface DataMapper { .column(ColumnBriefDto.builder() .name(columnName) .internalName(columnName) - .databaseId(table.getTdbid()) + .databaseId(table.getDatabaseId()) .build()) .referencedColumn(ColumnBriefDto.builder() .name(referencedColumnName) .internalName(referencedColumnName) - .databaseId(table.getTdbid()) + .databaseId(table.getDatabaseId()) .build()) .build(); if (optional1.isPresent()) { @@ -295,7 +294,7 @@ public interface DataMapper { .referencedTable(TableBriefDto.builder() .name(referencedTable) .internalName(referencedTable) - .databaseId(table.getTdbid()) + .databaseId(table.getDatabaseId()) .build()) .references(new LinkedList<>(List.of(foreignKeyReference))) .onDelete(deleteRule) @@ -325,7 +324,7 @@ public interface DataMapper { .avgRowLength(resultSet.getLong(4)) .dataLength(resultSet.getLong(5)) .maxDataLength(resultSet.getLong(6)) - .tdbid(database.getId()) + .databaseId(database.getId()) .queueName("dbrepo") .routingKey("dbrepo") .description(resultSet.getString(10)) diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java index 4e48c02786ba60cfed541c80048e921fc39d6b61..7b28a9b2ed9297aa6bf775b172d5803f667ad663 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java @@ -1,5 +1,11 @@ package at.tuwien.mapper; +import at.tuwien.api.container.image.OperatorDto; +import at.tuwien.api.database.DatabaseDto; +import at.tuwien.api.database.query.FilterDto; +import at.tuwien.api.database.query.FilterTypeDto; +import at.tuwien.api.database.query.OrderDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.api.database.table.TableDto; import at.tuwien.api.database.table.TupleDeleteDto; import at.tuwien.api.database.table.TupleDto; @@ -7,9 +13,15 @@ import at.tuwien.api.database.table.TupleUpdateDto; import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; import at.tuwien.api.database.table.columns.CreateTableColumnDto; +import at.tuwien.exception.ImageNotFoundException; import at.tuwien.exception.QueryMalformedException; import at.tuwien.exception.TableMalformedException; +import at.tuwien.exception.TableNotFoundException; import at.tuwien.utils.MariaDbUtil; +import org.jooq.Record; +import org.jooq.*; +import org.jooq.conf.ParamType; +import org.jooq.conf.StatementType; import org.mapstruct.Mapper; import org.mapstruct.Named; @@ -27,6 +39,9 @@ import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.select; + @Mapper(componentModel = "spring", uses = {MetadataMapper.class, DataMapper.class}) public interface MariaDbMapper { @@ -173,10 +188,14 @@ public interface MariaDbMapper { } @Named("dropView") - default String dropViewRawQuery(String viewName) { - final String statement = "DROP VIEW IF EXISTS `" + viewName + "`;"; + default String dropViewRawQuery(String databaseName, String viewName) { + final StringBuilder statement = new StringBuilder("DROP VIEW IF EXISTS `") + .append(databaseName) + .append("`.`") + .append(viewName) + .append("`;"); log.trace("mapped drop view statement: {}", statement); - return statement; + return statement.toString(); } default String databaseViewSelectRawQuery() { @@ -289,16 +308,21 @@ public interface MariaDbMapper { return statement.toString(); } - default String tableNameToUpdateTableRawQuery(String internalName) { + default String tableNameToUpdateTableRawQuery(String databaseName, String internalName) { final StringBuilder stringBuilder = new StringBuilder("ALTER TABLE `") + .append(databaseName) + .append("`.`") .append(internalName) .append("` COMMENT = ?;"); log.trace("mapped update table statement: {}", stringBuilder); return stringBuilder.toString(); } - default String tableCreateDtoToCreateTableRawQuery(at.tuwien.api.database.table.internal.TableCreateDto data) { + default String tableCreateDtoToCreateTableRawQuery(String databaseName, + at.tuwien.api.database.table.internal.TableCreateDto data) { final StringBuilder stringBuilder = new StringBuilder("CREATE TABLE `") + .append(databaseName) + .append("`.`") .append(nameToInternalName(data.getName())) .append("` ("); log.trace("PRIMARY KEY column(s) exist: {}", data.getConstraints().getPrimaryKey()); @@ -469,16 +493,18 @@ public interface MariaDbMapper { } @Named("dropTableQuery") - default String dropTableRawQuery(String tableName) { - return dropTableRawQuery(tableName, true); + default String dropTableRawQuery(String databaseName, String tableName) { + return dropTableRawQuery(databaseName, tableName, true); } - default String dropTableRawQuery(String tableName, Boolean force) { + default String dropTableRawQuery(String databaseName, String tableName, Boolean force) { final StringBuilder statement = new StringBuilder("DROP TABLE "); if (!force) { statement.append("IF EXISTS "); } statement.append("`") + .append(databaseName) + .append("`.`") .append(tableName) .append("`;"); log.trace("mapped drop table query: {}", statement); @@ -507,13 +533,15 @@ public interface MariaDbMapper { return statement.toString(); } - default String tupleToRawDeleteQuery(TableDto table, TupleDeleteDto data) throws TableMalformedException { + default String tupleToRawDeleteQuery(String databaseName, TableDto table, TupleDeleteDto data) throws TableMalformedException { log.trace("table csv to delete query, table.id={}, data.keys={}", table.getId(), data.getKeys()); if (table.getColumns().isEmpty()) { throw new TableMalformedException("Columns are not known"); } /* parameterized query for prepared statement */ final StringBuilder statement = new StringBuilder("DELETE FROM `") + .append(databaseName) + .append("`.`") .append(table.getInternalName()) .append("` WHERE "); final int[] idx = new int[]{0}; @@ -528,14 +556,14 @@ public interface MariaDbMapper { return statement.toString(); } - default String tupleToRawUpdateQuery(TableDto table, TupleUpdateDto data) + default String tupleToRawUpdateQuery(String databaseName, TableDto table, TupleUpdateDto data) throws TableMalformedException { if (table.getColumns().isEmpty()) { throw new TableMalformedException("Columns are not known"); } /* parameterized query for prepared statement */ final StringBuilder statement = new StringBuilder("UPDATE `") - .append(table.getDatabase().getInternalName()) + .append(databaseName) .append("`.`") .append(table.getInternalName()) .append("` SET "); @@ -567,13 +595,13 @@ public interface MariaDbMapper { return statement.toString(); } - default String tupleToRawCreateQuery(TableDto table, TupleDto data) throws TableMalformedException { + default String tupleToRawCreateQuery(String databaseName, TableDto table, TupleDto data) throws TableMalformedException { if (table.getColumns().isEmpty()) { throw new TableMalformedException("Columns are not known"); } /* parameterized query for prepared statement */ final StringBuilder statement = new StringBuilder("INSERT INTO `") - .append(table.getDatabase().getInternalName()) + .append(databaseName) .append("`.`") .append(table.getInternalName()) .append("` ("); @@ -788,4 +816,160 @@ public interface MariaDbMapper { return statement.toString(); } + default SelectConditionStep<Record> subsetDtoToSelectConditions(SelectJoinStep<Record> step, DatabaseDto database, + SubsetDto data) throws TableNotFoundException, + ImageNotFoundException { + if (data.getFilter() == null || data.getFilter().isEmpty()) { + return step.where(); + } + SelectConditionStep<Record> conditions = step.where(); + FilterTypeDto next = null; + for (int i = 0; i < data.getFilter().size(); i++) { + final FilterDto filter = data.getFilter().get(i); + final ColumnDto column = columnIdToColumnDto(database, filter.getColumnId()); + if (i == 0) { + conditions = step.where(filterDtoToCondition(database, column, filter)); + } else if (next != null) { + if (next.equals(FilterTypeDto.OR)) { + conditions = conditions.or(filterDtoToCondition(database, column, filter)); + } else if (next.equals(FilterTypeDto.AND)) { + conditions = conditions.and(filterDtoToCondition(database, column, filter)); + } + } + next = filter.getType(); + } + return conditions; + } + + default Condition filterDtoToCondition(DatabaseDto database, ColumnDto column, FilterDto data) + throws ImageNotFoundException { + final String operator = operatorIdToOperatorDto(database, data.getOperatorId()).getValue(); + switch (operator) { + case "=": + case "<=>": + return field(column.getInternalName()).eq(data.getValue()); + case "<": + return field(column.getInternalName()).lt(data.getValue()); + case "<=": + return field(column.getInternalName()).le(data.getValue()); + case ">": + return field(column.getInternalName()).gt(data.getValue()); + case ">=": + return field(column.getInternalName()).ge(data.getValue()); + case "!=": + return field(column.getInternalName()).ne(data.getValue()); + case "LIKE": + return field(column.getInternalName()).like(data.getValue()); + case "NOT LIKE": + return field(column.getInternalName()).notLike(data.getValue()); + case "IN": + return field(column.getInternalName()).in(data.getValue()); + case "NOT IN": + return field(column.getInternalName()).notIn(data.getValue()); + case "IS NOT NULL": + return field(column.getInternalName()).isNotNull(); + case "IS NULL": + return field(column.getInternalName()).isNull(); + case "REGEXP": + return field(column.getInternalName()).likeRegex(data.getValue()); + case "NOT REGEXP": + return field(column.getInternalName()).notLikeRegex(data.getValue()); + } + log.error("Failed to map operator: {}", operator); + throw new IllegalArgumentException("Failed to map operator: " + operator); + } + + default SelectSeekStepN<Record> subsetDtoToSelectOrder(SelectConditionStep<Record> step, DatabaseDto database, + SubsetDto data) throws TableNotFoundException { + final List<OrderField<Object>> sort = new LinkedList<>(); + for (OrderDto order : data.getOrder()) { + final ColumnDto column = columnIdToColumnDto(database, order.getColumnId()); + if (order.getDirection() == null) { + sort.add(field(column.getInternalName())); + continue; + } + switch (order.getDirection()) { + case ASC -> sort.add(field(column.getInternalName()).asc()); + case DESC -> sort.add(field(column.getInternalName()).desc()); + } + } + return step.orderBy(sort); + } + + default String subsetDtoToRawQuery(DatabaseDto database, SubsetDto data) throws TableNotFoundException, ImageNotFoundException { + final TableDto table = tableIdToTableDto(database, data.getTableId()); + final List<Field<Object>> columns = table.getColumns() + .stream() + .filter(c -> data.getColumns().contains(c.getId())) + .map(c -> field(c.getInternalName())) + .toList(); + final SelectJoinStep<Record> query = select(columns) + .from(table.getInternalName()); + final SelectConditionStep<Record> where = subsetDtoToSelectConditions(query, database, data); + final String sql; + if (data.getOrder() == null) { + sql = where.getSQL(ParamType.INLINED); + } else { + sql = subsetDtoToSelectOrder(where, database, data) + .getSQL(ParamType.INLINED); + } + log.trace("mapped prepared query: {}", sql); + return sql; + } + + default ColumnDto columnIdToColumnDto(TableDto table, UUID columnId) throws TableNotFoundException { + final Optional<ColumnDto> optional = table.getColumns() + .stream() + .filter(c -> c.getId().equals(columnId)) + .findFirst(); + if (optional.isEmpty()) { + log.error("Failed to find filtered column with id: {}", columnId); + throw new TableNotFoundException("Failed to find filtered column"); + } + return optional.get(); + } + + default ColumnDto columnIdToColumnDto(DatabaseDto database, UUID columnId) throws TableNotFoundException { + if (columnId == null) { + return null; + } + final Optional<ColumnDto> optional = database.getTables() + .stream() + .map(TableDto::getColumns) + .flatMap(List::stream) + .filter(column -> column.getId().equals(columnId)) + .findFirst(); + if (optional.isEmpty()) { + log.error("Failed to find column: {}", columnId); + throw new TableNotFoundException("Failed to find column"); + } + return optional.get(); + } + + default OperatorDto operatorIdToOperatorDto(DatabaseDto database, UUID operatorId) throws ImageNotFoundException { + final Optional<OperatorDto> optional = database.getContainer() + .getImage() + .getOperators() + .stream() + .filter(op -> op.getId().equals(operatorId)) + .findFirst(); + if (optional.isEmpty()) { + log.error("Failed to find operator with id: {}", operatorId); + throw new ImageNotFoundException("Failed to find operator"); + } + return optional.get(); + } + + default TableDto tableIdToTableDto(DatabaseDto database, UUID tableId) throws TableNotFoundException { + final Optional<TableDto> optional = database.getTables() + .stream() + .filter(t -> t.getId().equals(tableId)) + .findFirst(); + if (optional.isEmpty()) { + log.error("Failed to find table with id: {}", tableId); + throw new TableNotFoundException("Failed to find table"); + } + return optional.get(); + } + } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java index 803116e6029f0e540519832dbb4865f9964957d8..7bdf8fa14118f7f6cca621cf01e7567ce608dfdc 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MetadataMapper.java @@ -12,8 +12,10 @@ import at.tuwien.api.database.table.TableDto; import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.api.identifier.IdentifierBriefDto; import at.tuwien.api.identifier.IdentifierDto; +import at.tuwien.api.keycloak.TokenDto; import at.tuwien.api.user.UserBriefDto; import at.tuwien.api.user.UserDto; +import org.keycloak.representations.AccessTokenResponse; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -45,11 +47,13 @@ public interface MetadataMapper { UserDto userDtoToUserDto(UserDto data); - UserBriefDto userDtoToUserBriefDto(UserDto data); - @Mappings({ - @Mapping(target = "databaseId", source = "tdbid") + @Mapping(target = "accessToken", source = "token") }) + TokenDto accessTokenResponseToTokenDto(AccessTokenResponse data); + + UserBriefDto userDtoToUserBriefDto(UserDto data); + TableBriefDto tableDtoToTableBriefDto(TableDto data); IdentifierBriefDto identifierDtoToIdentifierBriefDto(IdentifierDto data); diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java similarity index 94% rename from dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java rename to dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java index 543e84ab51d03fa3c4c2a9992ce84700219efc01..c5ffcc1638253a942d7a04b562314082e94865dc 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/CredentialService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/CacheService.java @@ -10,7 +10,7 @@ import at.tuwien.exception.*; import java.util.UUID; -public interface CredentialService { +public interface CacheService { /** * Gets credentials for a database with given id either from the cache (if not expired) or retrieves them from the @@ -92,11 +92,4 @@ public interface CredentialService { */ DatabaseAccessDto getAccess(UUID databaseId, UUID userId) throws RemoteUnavailableException, MetadataServiceException, NotAllowedException; - - /** - * Invalidate the caches to force a refresh of access to a database with given id. - * - * @param databaseId The database id. - */ - void invalidateAccess(UUID databaseId); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java index c325d7b33a06b9dd5d773262d79a512893b67643..8f07b6bfb29d527e99fc85504bf00c15b5424f89 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java @@ -1,6 +1,5 @@ package at.tuwien.service; -import at.tuwien.api.database.CreateViewDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.table.TableDto; @@ -40,12 +39,13 @@ public interface DatabaseService { /** * Creates a view in given data database with view definition. * @param database The data database object. - * @param data The view definition. + * @param viewName The view name. + * @param query The view query. * @return The generated view. * @throws SQLException * @throws ViewMalformedException */ - ViewDto createView(DatabaseDto database, CreateViewDto data) throws SQLException, + ViewDto createView(DatabaseDto database, String viewName, String query) throws SQLException, ViewMalformedException; /** diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/QueueService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/QueueService.java index 6a03f5d767115314f6683ae726caaaf26538ebf9..1e8ba52923af628991d2994236378bab2e991e56 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/QueueService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/QueueService.java @@ -1,5 +1,6 @@ package at.tuwien.service; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.table.TableDto; import java.sql.SQLException; @@ -10,9 +11,10 @@ public interface QueueService { /** * Inserts data into the table of a given database. * + * @param database The database. * @param table The table. * @param data The data. * @throws SQLException The connection to the database could not be established. */ - void insert(TableDto table, Map<String, Object> data) throws SQLException; + void insert(DatabaseDto database, TableDto table, Map<String, Object> data) throws SQLException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java index 49bd560c7a6a247461a273815e6b9ed0913f1d5f..30d4baca5c0c4f555206f866cf886a4439dac58e 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java @@ -2,6 +2,7 @@ package at.tuwien.service; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.QueryDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.exception.*; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; @@ -17,15 +18,15 @@ public interface SubsetService { * Creates a subset from the given statement at given time in the given database. * * @param database The database. - * @param statement The subset statement. + * @param subset The subset information. * @param timestamp The timestamp as of which the data is queried. If smaller than <now>, historic data is queried. * @param userId The user id of the creating user. * @return The query id. * @throws QueryStoreInsertException The query store refused to insert the query. * @throws SQLException The connection to the database could not be established. */ - UUID create(DatabaseDto database, String statement, Instant timestamp, UUID userId) - throws QueryStoreInsertException, SQLException; + UUID create(DatabaseDto database, SubsetDto subset, Instant timestamp, UUID userId) + throws QueryStoreInsertException, SQLException, QueryMalformedException, TableNotFoundException, ImageNotFoundException, ViewMalformedException; /** * Counts the subset row count of a query of a given subset in the given database. @@ -33,11 +34,10 @@ public interface SubsetService { * @param database The database. * @param query The subset. * @return The row count. - * @throws TableMalformedException The table is malformed. + * @throws QueryMalformedException The query is malformed. * @throws SQLException The connection to the database could not be established. */ - Long reExecuteCount(DatabaseDto database, QueryDto query) throws TableMalformedException, - SQLException, QueryMalformedException; + Long reExecuteCount(DatabaseDto database, QueryDto query) throws SQLException, QueryMalformedException; /** * Retrieve data from a subset in a database and optionally paginate with number of page and size of results. @@ -74,10 +74,9 @@ public interface SubsetService { * @return The row count. * @throws SQLException The connection to the database could not be established. * @throws QueryMalformedException The mapped query produced a database error. - * @throws TableMalformedException The database table is malformed. */ Long executeCountNonPersistent(DatabaseDto database, String statement, Instant timestamp) - throws SQLException, QueryMalformedException, TableMalformedException; + throws SQLException, QueryMalformedException; /** * Finds a query in the query store of the given database id and query id. @@ -99,14 +98,14 @@ public interface SubsetService { * Inserts a query and metadata to the query store of a given database id. * * @param database The database. - * @param query The query statement. + * @param statement The query statement. * @param userId The user id. * @return The stored query id on success. * @throws SQLException The connection to the database could not be established. * @throws QueryStoreInsertException The query store failed to insert the query. */ - UUID storeQuery(DatabaseDto database, String query, Instant timestamp, UUID userId) throws SQLException, - QueryStoreInsertException; + UUID storeQuery(DatabaseDto database, String statement, Instant timestamp, UUID userId) throws SQLException, + QueryStoreInsertException, ViewMalformedException; /** * Persists a query to be displayed in the frontend. diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java index f664a82cf32050512f5eeb7d9e2b206289153568..bb2b53432c41e0a521165c0bbdfb197579936331 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java @@ -1,5 +1,6 @@ package at.tuwien.service; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.table.*; import at.tuwien.exception.*; @@ -19,7 +20,7 @@ public interface TableService { * @throws TableMalformedException The table statistic generation was unsuccessful, likely due to a bug in the mapping. * @throws TableNotFoundException The table could not be inspected in the data database. */ - TableStatisticDto getStatistics(TableDto table) throws SQLException, TableMalformedException, + TableStatisticDto getStatistics(DatabaseDto database, TableDto table) throws SQLException, TableMalformedException, TableNotFoundException; /** @@ -31,7 +32,7 @@ public interface TableService { * @throws TableMalformedException The table schema is malformed. * @throws TableNotFoundException The table could not be inspected in the metadata database. */ - void updateTable(TableDto table, TableUpdateDto data) throws SQLException, + void updateTable(DatabaseDto database, TableDto table, TableUpdateDto data) throws SQLException, TableMalformedException, TableNotFoundException; /** @@ -41,7 +42,7 @@ public interface TableService { * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The drop table query is malformed. */ - void delete(TableDto table) throws SQLException, QueryMalformedException; + void delete(DatabaseDto database, TableDto table) throws SQLException, QueryMalformedException; /** * Obtains the table history for a given table object. @@ -52,7 +53,7 @@ public interface TableService { * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws TableNotFoundException The table could not be found in the data database. */ - List<TableHistoryDto> history(TableDto table, Long size) throws SQLException, TableNotFoundException; + List<TableHistoryDto> history(DatabaseDto database, TableDto table, Long size) throws SQLException, TableNotFoundException; /** * Obtains the table data tuples count at time. @@ -63,7 +64,7 @@ public interface TableService { * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The count query is malformed, likely due to a bug in the application. */ - Long getCount(TableDto table, Instant timestamp) throws SQLException, + Long getCount(DatabaseDto database, TableDto table, Instant timestamp) throws SQLException, QueryMalformedException; /** @@ -78,7 +79,7 @@ public interface TableService { * @throws SQLException Failed to parse SQL query, contains invalid syntax. * @throws QueryMalformedException The import query is malformed, likely due to a bug in the application. */ - void importDataset(TableDto table, ImportDto data) throws MalformedException, StorageNotFoundException, + void importDataset(DatabaseDto database, TableDto table, ImportDto data) throws MalformedException, StorageNotFoundException, StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException; /** @@ -90,7 +91,7 @@ public interface TableService { * @throws TableMalformedException The tuple is malformed and does not fit the table schema. * @throws QueryMalformedException The delete query is malformed, likely due to a bug in the application. */ - void deleteTuple(TableDto table, TupleDeleteDto data) throws SQLException, + void deleteTuple(DatabaseDto database, TableDto table, TupleDeleteDto data) throws SQLException, TableMalformedException, QueryMalformedException; /** @@ -104,7 +105,7 @@ public interface TableService { * @throws StorageUnavailableException Failed to establish a connection with the Storage Service. * @throws StorageNotFoundException The storage service was not able to find the dataset for import. */ - void createTuple(TableDto table, TupleDto data) throws SQLException, + void createTuple(DatabaseDto database, TableDto table, TupleDto data) throws SQLException, QueryMalformedException, TableMalformedException, StorageUnavailableException, StorageNotFoundException; /** @@ -116,6 +117,6 @@ public interface TableService { * @throws QueryMalformedException The update query is malformed, likely due to a bug in the application. * @throws TableMalformedException The tuple is malformed and does not fit the table schema. */ - void updateTuple(TableDto table, TupleUpdateDto data) throws SQLException, + void updateTuple(DatabaseDto database, TableDto table, TupleUpdateDto data) throws SQLException, QueryMalformedException, TableMalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java index 8f721f9974b0a35d5158fba0d67f9bf7a95faf70..7f64f72ebefeb7daa3811aedf5f41765e2ec28d6 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/ViewService.java @@ -1,5 +1,6 @@ package at.tuwien.service; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.exception.QueryMalformedException; import at.tuwien.exception.ViewMalformedException; @@ -12,20 +13,22 @@ public interface ViewService { /** * Deletes a view. * + * @param database The database. * @param view The view. * @throws SQLException The connection to the data database was unsuccessful. * @throws ViewMalformedException The query is malformed and was rejected by the data database. */ - void delete(ViewDto view) throws SQLException, ViewMalformedException; + void delete(DatabaseDto database, ViewDto view) throws SQLException, ViewMalformedException; /** * Counts tuples in a view at system-versioned timestamp. * + * @param database The database. * @param view The view. * @param timestamp The system-versioned timestamp. * @return The number of tuples. * @throws SQLException The connection to the data database was unsuccessful. * @throws QueryMalformedException The query is malformed and was rejected by the data database. */ - Long count(ViewDto view, Instant timestamp) throws SQLException, QueryMalformedException; + Long count(DatabaseDto database, ViewDto view, Instant timestamp) throws SQLException, QueryMalformedException; } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java similarity index 88% rename from dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java rename to dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java index 8f3553515f386afcc91627a0cecd11a05d263f27..c23f77edd68af67fbe09d3d9c5b4746b3eebbd83 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CredentialServiceImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/CacheServiceImpl.java @@ -8,7 +8,7 @@ import at.tuwien.api.database.table.TableDto; import at.tuwien.api.user.UserDto; import at.tuwien.exception.*; import at.tuwien.gateway.MetadataServiceGateway; -import at.tuwien.service.CredentialService; +import at.tuwien.service.CacheService; import com.github.benmanes.caffeine.cache.Cache; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +18,7 @@ import java.util.UUID; @Log4j2 @Service -public class CredentialServiceImpl implements CredentialService { +public class CacheServiceImpl implements CacheService { private final MetadataServiceGateway gateway; private final Cache<UUID, UserDto> userCache; @@ -29,10 +29,10 @@ public class CredentialServiceImpl implements CredentialService { private final Cache<UUID, DatabaseAccessDto> accessCache; @Autowired - public CredentialServiceImpl(MetadataServiceGateway gateway, Cache<UUID, UserDto> userCache, - Cache<UUID, ViewDto> viewCache, Cache<UUID, TableDto> tableCache, - Cache<UUID, DatabaseAccessDto> accessCache, Cache<UUID, DatabaseDto> databaseCache, - Cache<UUID, ContainerDto> containerCache) { + public CacheServiceImpl(MetadataServiceGateway gateway, Cache<UUID, UserDto> userCache, + Cache<UUID, ViewDto> viewCache, Cache<UUID, TableDto> tableCache, + Cache<UUID, DatabaseAccessDto> accessCache, Cache<UUID, DatabaseDto> databaseCache, + Cache<UUID, ContainerDto> containerCache) { this.gateway = gateway; this.userCache = userCache; this.viewCache = viewCache; @@ -70,12 +70,6 @@ public class CredentialServiceImpl implements CredentialService { return table; } - @Override - public void invalidateAccess(UUID databaseId) { - accessCache.invalidate(databaseId); - log.debug("invalidated access for database with id {} in cache", databaseId); - } - @Override public ContainerDto getContainer(UUID id) throws RemoteUnavailableException, MetadataServiceException, ContainerNotFoundException { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java index 37a345426ae560aee202d5acbcc4d62d79f85f2b..6e6e316b5af1b2e21cbc3f0d1ad1dc7e2232dca4 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java @@ -2,8 +2,6 @@ package at.tuwien.service.impl; import at.tuwien.api.container.ContainerDto; import at.tuwien.api.database.DatabaseDto; -import at.tuwien.api.database.ViewDto; -import at.tuwien.api.database.table.TableDto; import com.mchange.v2.c3p0.ComboPooledDataSource; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; @@ -25,14 +23,6 @@ public abstract class DataConnector { return dataSource; } - public ComboPooledDataSource getDataSource(ViewDto view) { - return getDataSource(view.getDatabase().getContainer(), view.getDatabase().getInternalName()); - } - - public ComboPooledDataSource getDataSource(TableDto table) { - return getDataSource(table.getDatabase().getContainer(), table.getDatabase().getInternalName()); - } - public ComboPooledDataSource getDataSource(ContainerDto container) { return getDataSource(container, null); } @@ -48,10 +38,6 @@ public abstract class DataConnector { return sb.toString(); } - public String getSparkUrl(TableDto table) { - return getSparkUrl(table.getDatabase().getContainer(), table.getDatabase().getInternalName()); - } - public String getSparkUrl(DatabaseDto databaseDto) { return getSparkUrl(databaseDto.getContainer(), databaseDto.getInternalName()); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java index f7e12c69f6d2937850d0e2d9a2973b1e6e7dadf2..846fa86a4c967c04ed1a6b9c2b60befdbe82096c 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java @@ -1,6 +1,5 @@ package at.tuwien.service.impl; -import at.tuwien.api.database.CreateViewDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.table.TableDto; @@ -59,7 +58,7 @@ public class DatabaseServiceMariaDbImpl extends DataConnector implements Databas throw new ViewNotFoundException("Failed to find view in the information schema"); } final ViewDto view = dataMapper.schemaResultSetToView(database, resultSet1); - view.setVdbid(database.getId()); + view.setDatabaseId(database.getId()); view.setOwner(database.getOwner()); /* obtain view columns */ start = System.currentTimeMillis(); @@ -97,7 +96,8 @@ public class DatabaseServiceMariaDbImpl extends DataConnector implements Databas try { /* create table if not exists */ final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.tableCreateDtoToCreateTableRawQuery(data)) + connection.prepareStatement(mariaDbMapper.tableCreateDtoToCreateTableRawQuery(database.getInternalName(), + data)) .execute(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); connection.commit(); @@ -112,34 +112,33 @@ public class DatabaseServiceMariaDbImpl extends DataConnector implements Databas } finally { dataSource.close(); } - log.info("Created table with name {}", tableName); - final TableDto table = inspectTable(database, tableName); - return table; + log.info("Created table with name {}.{}", database.getInternalName(), tableName); + return inspectTable(database, tableName); } @Override - public ViewDto createView(DatabaseDto database, CreateViewDto data) throws SQLException, + public ViewDto createView(DatabaseDto database, String viewName, String query) throws SQLException, ViewMalformedException { final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); ViewDto view = ViewDto.builder() - .name(data.getName()) - .internalName(mariaDbMapper.nameToInternalName(data.getName())) - .query(data.getQuery()) + .name(viewName) + .internalName(mariaDbMapper.nameToInternalName(viewName)) + .query(query) .queryHash(Hashing.sha256() - .hashString(data.getQuery(), StandardCharsets.UTF_8) + .hashString(query, StandardCharsets.UTF_8) .toString()) .isPublic(database.getIsPublic()) .owner(database.getOwner()) .identifiers(new LinkedList<>()) .isInitialView(false) - .vdbid(database.getId()) + .databaseId(database.getId()) .columns(new LinkedList<>()) .build(); try { /* create view if not exists */ final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.viewCreateRawQuery(view.getInternalName(), data.getQuery())) + connection.prepareStatement(mariaDbMapper.viewCreateRawQuery(view.getInternalName(), query)) .execute(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); /* select view columns */ @@ -293,7 +292,7 @@ public class DatabaseServiceMariaDbImpl extends DataConnector implements Databas }); } } - table.setTdbid(database.getId()); + table.setDatabaseId(database.getId()); table.setOwner(database.getOwner()); final TableDto tmpTable = table; tmpTable.getColumns() diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/QueueServiceRabbitMqImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/QueueServiceRabbitMqImpl.java index 4db29335fbfc4cbdbb8086a2009cb588613d1969..07b889d536c14719988c768b16998ab9fcc1b55c 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/QueueServiceRabbitMqImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/QueueServiceRabbitMqImpl.java @@ -1,5 +1,6 @@ package at.tuwien.service.impl; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.table.TableDto; import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.mapper.DataMapper; @@ -30,13 +31,14 @@ public class QueueServiceRabbitMqImpl extends DataConnector implements QueueServ } @Override - public void insert(TableDto table, Map<String, Object> data) throws SQLException { - final ComboPooledDataSource dataSource = getDataSource(table); + public void insert(DatabaseDto database, TableDto table, Map<String, Object> data) throws SQLException { + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { final int[] idx = new int[]{1}; final PreparedStatement preparedStatement = connection.prepareStatement( - dataMapper.rabbitMqTupleToInsertOrUpdateQuery(metadataMapper.tableDtoToTableDto(table), data)); + dataMapper.rabbitMqTupleToInsertOrUpdateQuery(database.getInternalName(), + metadataMapper.tableDtoToTableDto(table), data)); for (Map.Entry<String, Object> entry : data.entrySet()) { final Optional<ColumnDto> optional = table.getColumns().stream().filter(c -> c.getInternalName().equals(entry.getKey())).findFirst(); if (optional.isEmpty()) { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java index 8adaae9c6a065296fd42ea66e5cad8328cc6e06a..869f12bde2b6182d4ca1504a76d33019a55d6c97 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java @@ -2,6 +2,7 @@ package at.tuwien.service.impl; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.QueryDto; +import at.tuwien.api.database.query.SubsetDto; import at.tuwien.api.identifier.IdentifierBriefDto; import at.tuwien.api.identifier.IdentifierTypeDto; import at.tuwien.exception.*; @@ -53,11 +54,10 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer .option("query", query) .load(); } catch (Exception e) { - if (e instanceof ExtendedAnalysisException exception) { - if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) { - log.error("Failed to find named reference: {}", exception.getSimpleMessage()); - throw new TableNotFoundException("Failed to find named reference: " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */; - } + if (e instanceof ExtendedAnalysisException && e.getMessage().contains("TABLE_OR_VIEW_NOT_FOUND") + || e instanceof SQLSyntaxErrorException && e.getMessage().contains("doesn't exist")) { + log.error("Failed to find named reference: {}", e.getMessage()); + throw new TableNotFoundException("Failed to find named reference: " + e.getMessage()) /* remove throwable on purpose, clutters the output */; } log.error("Malformed query: {}", e.getMessage()); throw new QueryMalformedException("Malformed query: " + e.getMessage(), e); @@ -65,14 +65,15 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer } @Override - public UUID create(DatabaseDto database, String statement, Instant timestamp, UUID userId) - throws QueryStoreInsertException, SQLException { + public UUID create(DatabaseDto database, SubsetDto subset, Instant timestamp, UUID userId) + throws QueryStoreInsertException, SQLException, QueryMalformedException, TableNotFoundException, + ImageNotFoundException, ViewMalformedException { + final String statement = mariaDbMapper.subsetDtoToRawQuery(database, subset); return storeQuery(database, statement, timestamp, userId); } @Override - public Long reExecuteCount(DatabaseDto database, QueryDto query) throws TableMalformedException, - SQLException, QueryMalformedException { + public Long reExecuteCount(DatabaseDto database, QueryDto query) throws SQLException, QueryMalformedException { return executeCountNonPersistent(database, query.getQuery(), query.getExecution()); } @@ -112,7 +113,7 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer @Override public Long executeCountNonPersistent(DatabaseDto database, String statement, Instant timestamp) - throws SQLException, QueryMalformedException, TableMalformedException { + throws SQLException, QueryMalformedException { final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { @@ -123,7 +124,7 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer return mariaDbMapper.resultSetToNumber(resultSet); } catch (SQLException e) { log.error("Failed to map object: {}", e.getMessage()); - throw new TableMalformedException("Failed to map object: " + e.getMessage(), e); + throw new QueryMalformedException("Failed to map object: " + e.getMessage(), e); } finally { dataSource.close(); } diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java index 466f7539fd250666962d08a75ffffd5aa61480fa..a646de02b3b560a7dc6967c108a4f7369e33fd65 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java @@ -1,5 +1,6 @@ package at.tuwien.service.impl; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.query.ImportDto; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.columns.ColumnDto; @@ -50,9 +51,9 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } @Override - public TableStatisticDto getStatistics(TableDto table) throws SQLException, TableMalformedException, + public TableStatisticDto getStatistics(DatabaseDto database, TableDto table) throws SQLException, TableMalformedException, TableNotFoundException { - final ComboPooledDataSource dataSource = getDataSource(table); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); final TableStatisticDto statistic; try { @@ -60,14 +61,14 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi final long start = System.currentTimeMillis(); final String query = mariaDbMapper.tableColumnStatisticsSelectRawQuery(table.getColumns(), table.getInternalName()); if (query == null) { - log.debug("table {}.{} does not have columns that can be analysed for statistical properties (i.e. no numeric columns)", table.getDatabase().getInternalName(), table.getInternalName()); + log.debug("table {}.{} does not have columns that can be analysed for statistical properties", database.getInternalName(), table.getInternalName()); statistic = null; } else { final ResultSet resultSet = connection.prepareStatement(query) .executeQuery(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); statistic = dataMapper.resultSetToTableStatistic(resultSet); - final TableDto tmpTable = databaseService.inspectTable(table.getDatabase(), table.getInternalName()); + final TableDto tmpTable = databaseService.inspectTable(database, table.getInternalName()); statistic.setAvgRowLength(tmpTable.getAvgRowLength()); statistic.setDataLength(tmpTable.getDataLength()); statistic.setMaxDataLength(tmpTable.getMaxDataLength()); @@ -91,14 +92,15 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } @Override - public void updateTable(TableDto table, TableUpdateDto data) throws SQLException, + public void updateTable(DatabaseDto database, TableDto table, TableUpdateDto data) throws SQLException, TableMalformedException { - final ComboPooledDataSource dataSource = getDataSource(table.getDatabase()); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* create table if not exists */ final long start = System.currentTimeMillis(); - final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tableNameToUpdateTableRawQuery(table.getInternalName())); + final PreparedStatement statement = connection.prepareStatement( + mariaDbMapper.tableNameToUpdateTableRawQuery(database.getInternalName(), table.getInternalName())); log.trace("prepare with arg 1={}", data.getDescription()); if (data.getDescription() == null) { statement.setString(1, ""); @@ -115,17 +117,18 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } finally { dataSource.close(); } - log.info("Updated table with name {}", table.getInternalName()); + log.info("Updated table with name {}.{}", database.getInternalName(), table.getInternalName()); } @Override - public void delete(TableDto table) throws SQLException, QueryMalformedException { - final ComboPooledDataSource dataSource = getDataSource(table.getDatabase()); + public void delete(DatabaseDto database, TableDto table) throws SQLException, QueryMalformedException { + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* create table if not exists */ final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.dropTableRawQuery(table.getInternalName())) + connection.prepareStatement(mariaDbMapper.dropTableRawQuery(database.getInternalName(), + table.getInternalName())) .execute(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); connection.commit(); @@ -136,63 +139,63 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } finally { dataSource.close(); } - log.info("Deleted table with name {}", table.getInternalName()); + log.info("Deleted table with name {}.{}", database.getInternalName(), table.getInternalName()); } @Override - public List<TableHistoryDto> history(TableDto table, Long size) throws SQLException, + public List<TableHistoryDto> history(DatabaseDto database, TableDto table, Long size) throws SQLException, TableNotFoundException { - final ComboPooledDataSource dataSource = getDataSource(table.getDatabase()); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); final List<TableHistoryDto> history; try { /* find table data */ final long start = System.currentTimeMillis(); final ResultSet resultSet = connection.prepareStatement(mariaDbMapper.selectHistoryRawQuery( - table.getDatabase().getInternalName(), table.getInternalName(), size)) + database.getInternalName(), table.getInternalName(), size)) .executeQuery(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); history = dataMapper.resultSetToTableHistory(resultSet); connection.commit(); } catch (SQLException e) { connection.rollback(); - log.error("Failed to find history for table {}.{}: {}", table.getDatabase(), table.getInternalName(), e.getMessage()); - throw new TableNotFoundException("Failed to find history for table " + table.getDatabase() + "." + table.getInternalName() + ": " + e.getMessage(), e); + log.error("Failed to find history for table {}.{}: {}", database, table.getInternalName(), e.getMessage()); + throw new TableNotFoundException("Failed to find history for table " + database + "." + table.getInternalName() + ": " + e.getMessage(), e); } finally { dataSource.close(); } - log.info("Find history for table {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Find history for table {}.{}", database.getInternalName(), table.getInternalName()); return history; } @Override - public Long getCount(TableDto table, Instant timestamp) throws SQLException, + public Long getCount(DatabaseDto database, TableDto table, Instant timestamp) throws SQLException, QueryMalformedException { - final ComboPooledDataSource dataSource = getDataSource(table.getDatabase()); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); final Long queryResult; try { /* find table data */ final long start = System.currentTimeMillis(); final ResultSet resultSet = connection.prepareStatement(mariaDbMapper.selectCountRawQuery( - table.getDatabase().getInternalName(), table.getInternalName(), timestamp)) + database.getInternalName(), table.getInternalName(), timestamp)) .executeQuery(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); queryResult = mariaDbMapper.resultSetToNumber(resultSet); connection.commit(); } catch (SQLException e) { connection.rollback(); - log.error("Failed to find row count from table {}.{}: {}", table.getDatabase(), table.getInternalName(), e.getMessage()); - throw new QueryMalformedException("Failed to find row count from table " + table.getDatabase() + "." + table.getInternalName() + ": " + e.getMessage(), e); + log.error("Failed to find row count from table {}.{}: {}", database, table.getInternalName(), e.getMessage()); + throw new QueryMalformedException("Failed to find row count from table " + database + "." + table.getInternalName() + ": " + e.getMessage(), e); } finally { dataSource.close(); } - log.info("Find row count from table {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Find row count from table {}.{}", database.getInternalName(), table.getInternalName()); return queryResult; } @Override - public void importDataset(TableDto table, ImportDto data) throws MalformedException, + public void importDataset(DatabaseDto database, TableDto table, ImportDto data) throws MalformedException, StorageNotFoundException, StorageUnavailableException, SQLException, QueryMalformedException, TableMalformedException { final List<String> columns = table.getColumns() @@ -202,8 +205,8 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi final Dataset<Row> dataset = storageService.loadDataset(columns, data.getLocation(), String.valueOf(data.getSeparator()), data.getHeader()); final Properties properties = new Properties(); - properties.setProperty("user", table.getDatabase().getContainer().getUsername()); - properties.setProperty("password", table.getDatabase().getContainer().getPassword()); + properties.setProperty("user", database.getContainer().getUsername()); + properties.setProperty("password", database.getContainer().getPassword()); final String temporaryTable = table.getInternalName() + "_tmp"; try { log.trace("import dataset to temporary table: {}", temporaryTable); @@ -211,7 +214,7 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi .mode(SaveMode.Overwrite) .option("header", data.getHeader()) .option("inferSchema", "true") - .jdbc(getSparkUrl(table), temporaryTable, properties); + .jdbc(getSparkUrl(database), temporaryTable, properties); } catch (Exception e) { if (e instanceof AnalysisException exception) { final String message = exception.getSimpleMessage() @@ -222,8 +225,8 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi log.error("Failed to write dataset: {}", e.getMessage()); throw new MalformedException("Failed to write dataset: " + e.getMessage()) /* remove throwable on purpose, clutters the output */; } - /* import .csv from sidecar to database */ - final ComboPooledDataSource dataSource = getDataSource(table); + /* import .csv to database */ + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* import tuple */ @@ -237,25 +240,27 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi throw new QueryMalformedException("Failed to import tuple: " + e.getMessage(), e); } finally { /* delete temporary table */ - connection.prepareStatement(mariaDbMapper.dropTableRawQuery(temporaryTable, false)) + connection.prepareStatement(mariaDbMapper.dropTableRawQuery(database.getInternalName(), temporaryTable, + false)) .execute(); connection.commit(); dataSource.close(); } - log.info("Imported dataset into table: {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Imported dataset into table: {}.{}", database, table.getInternalName()); } @Override - public void deleteTuple(TableDto table, TupleDeleteDto data) throws SQLException, + public void deleteTuple(DatabaseDto database, TableDto table, TupleDeleteDto data) throws SQLException, TableMalformedException, QueryMalformedException { log.trace("delete tuple: {}", data); /* prepare the statement */ - final ComboPooledDataSource dataSource = getDataSource(table); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* import tuple */ final int[] idx = new int[]{1}; - final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawDeleteQuery(table, data)); + final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawDeleteQuery( + database.getInternalName(), table, data)); for (String column : data.getKeys().keySet()) { mariaDbMapper.prepareStatementWithColumnTypeObject(statement, getColumnType(table.getColumns(), column), idx[0], column, data.getKeys().get(column)); @@ -272,12 +277,12 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } finally { dataSource.close(); } - log.info("Deleted tuple(s) from table: {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Deleted tuple(s) from table: {}.{}", database.getInternalName(), table.getInternalName()); } @Override - public void createTuple(TableDto table, TupleDto data) throws SQLException, QueryMalformedException, - TableMalformedException, StorageUnavailableException, StorageNotFoundException { + public void createTuple(DatabaseDto database, TableDto table, TupleDto data) throws SQLException, + QueryMalformedException, TableMalformedException, StorageUnavailableException, StorageNotFoundException { log.trace("create tuple: {}", data); /* for each LOB-like data-column, retrieve the bytes and replace the value */ for (String key : data.getData().keySet()) { @@ -294,12 +299,13 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi .replace(key, blob); } /* prepare the statement */ - final ComboPooledDataSource dataSource = getDataSource(table); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* create tuple */ final int[] idx = new int[]{1}; - final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawCreateQuery(table, data)); + final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawCreateQuery( + database.getInternalName(), table, data)); for (Map.Entry<String, Object> entry : data.getData().entrySet()) { mariaDbMapper.prepareStatementWithColumnTypeObject(statement, getColumnType(table.getColumns(), entry.getKey()), idx[0], entry.getKey(), entry.getValue()); @@ -316,19 +322,20 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } finally { dataSource.close(); } - log.info("Created tuple(s) in table: {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Created tuple(s) in table: {}.{}", database.getInternalName(), table.getInternalName()); } @Override - public void updateTuple(TableDto table, TupleUpdateDto data) throws SQLException, + public void updateTuple(DatabaseDto database, TableDto table, TupleUpdateDto data) throws SQLException, QueryMalformedException, TableMalformedException { log.trace("update tuple: {}", data); /* prepare the statement */ - final ComboPooledDataSource dataSource = getDataSource(table); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { final int[] idx = new int[]{1}; - final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawUpdateQuery(table, data)); + final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawUpdateQuery( + database.getInternalName(), table, data)); /* set data */ for (Map.Entry<String, Object> entry : data.getData().entrySet()) { mariaDbMapper.prepareStatementWithColumnTypeObject(statement, @@ -352,7 +359,7 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi } finally { dataSource.close(); } - log.info("Updated tuple(s) from table: {}.{}", table.getDatabase(), table.getInternalName()); + log.info("Updated tuple(s) from table: {}.{}", database.getInternalName(), table.getInternalName()); } public ColumnTypeDto getColumnType(List<ColumnDto> columns, String name) throws QueryMalformedException { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java index fff524047e10b575f773fe23656f86944514843a..c1ba33ae4ae91639ba14d715a569b4b596880625 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/ViewServiceMariaDbImpl.java @@ -1,5 +1,6 @@ package at.tuwien.service.impl; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.ViewDto; import at.tuwien.exception.QueryMalformedException; import at.tuwien.exception.ViewMalformedException; @@ -27,13 +28,14 @@ public class ViewServiceMariaDbImpl extends DataConnector implements ViewService } @Override - public void delete(ViewDto view) throws SQLException, ViewMalformedException { - final ComboPooledDataSource dataSource = getDataSource(view); + public void delete(DatabaseDto database, ViewDto view) throws SQLException, ViewMalformedException { + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { /* drop view if exists */ final long start = System.currentTimeMillis(); - connection.prepareStatement(mariaDbMapper.dropViewRawQuery(view.getInternalName())) + connection.prepareStatement(mariaDbMapper.dropViewRawQuery(database.getInternalName(), + view.getInternalName())) .execute(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); connection.commit(); @@ -44,32 +46,32 @@ public class ViewServiceMariaDbImpl extends DataConnector implements ViewService } finally { dataSource.close(); } - log.info("Deleted view {}.{}", view.getDatabase(), view.getInternalName()); + log.info("Deleted view {}.{}", database.getInternalName(), view.getInternalName()); } @Override - public Long count(ViewDto view, Instant timestamp) throws SQLException, + public Long count(DatabaseDto database, ViewDto view, Instant timestamp) throws SQLException, QueryMalformedException { - final ComboPooledDataSource dataSource = getDataSource(view); + final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); final Long queryResult; try { /* find view data */ final long start = System.currentTimeMillis(); final ResultSet resultSet = connection.prepareStatement(mariaDbMapper.selectCountRawQuery( - view.getDatabase().getInternalName(), view.getInternalName(), timestamp)) + database.getInternalName(), view.getInternalName(), timestamp)) .executeQuery(); log.trace("executed statement in {} ms", System.currentTimeMillis() - start); queryResult = mariaDbMapper.resultSetToNumber(resultSet); connection.commit(); } catch (SQLException e) { connection.rollback(); - log.error("Failed to find row count from view {}.{}: {}", view.getDatabase(), view.getInternalName(), e.getMessage()); - throw new QueryMalformedException("Failed to find row count from view " + view.getDatabase() + "." + view.getInternalName() + ": " + e.getMessage(), e); + log.error("Failed to find row count from view {}.{}: {}", database.getInternalName(), view.getInternalName(), e.getMessage()); + throw new QueryMalformedException("Failed to find row count from view " + database.getInternalName() + "." + view.getInternalName() + ": " + e.getMessage(), e); } finally { dataSource.close(); } - log.info("Find row count from view {}.{}", view.getDatabase(), view.getInternalName()); + log.info("Find row count from view {}.{}", database.getInternalName(), view.getInternalName()); return queryResult; } diff --git a/dbrepo-metadata-db/1_setup-schema.sql b/dbrepo-metadata-db/1_setup-schema.sql index 17d303ea7d6001e73a55b19cc286e8d9980e1d35..12e0f02a169c969ea0036652dc2198b79e492ebf 100644 --- a/dbrepo-metadata-db/1_setup-schema.sql +++ b/dbrepo-metadata-db/1_setup-schema.sql @@ -280,6 +280,7 @@ CREATE TABLE IF NOT EXISTS `mdb_view` last_modified TIMESTAMP, owned_by VARCHAR(36) NOT NULL, PRIMARY KEY (`id`), + UNIQUE (`vdbid`, `internal_name`), FOREIGN KEY (`vdbid`) REFERENCES mdb_databases (`id`), FOREIGN KEY (`owned_by`) REFERENCES mdb_users (`id`) ) WITH SYSTEM VERSIONING; @@ -596,32 +597,14 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Equal operator', '=', ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Greater than or equal operator', '>=', 'https://mariadb.com/kb/en/greater-than-or-equal/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Not equal operator', '!=', 'https://mariadb.com/kb/en/not-equal/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Addition operator', '+', - 'https://mariadb.com/kb/en/addition-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Division operator', '/', - 'https://mariadb.com/kb/en/division-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Modulo operator', '%', 'https://mariadb.com/kb/en/modulo-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Multiplication operator', '*', - 'https://mariadb.com/kb/en/multiplication-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Subtraction operator', '-', - 'https://mariadb.com/kb/en/subtraction-operator-/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LIKE', 'LIKE', 'https://mariadb.com/kb/en/like/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT LIKE', 'NOT LIKE', 'https://mariadb.com/kb/en/not-like/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IN', 'IN', 'https://mariadb.com/kb/en/in/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT IN', 'NOT IN', 'https://mariadb.com/kb/en/not-in/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS', 'IS', 'https://mariadb.com/kb/en/is/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NOT', 'IS NOT', 'https://mariadb.com/kb/en/is-not/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NOT NULL', 'IS NOT NULL', 'https://mariadb.com/kb/en/is-not-null/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NULL', 'IS NULL', 'https://mariadb.com/kb/en/is-null/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ISNULL', 'ISNULL', 'https://mariadb.com/kb/en/isnull/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'REGEXP', 'REGEXP', 'https://mariadb.com/kb/en/regexp/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT REGEXP', 'NOT REGEXP', 'https://mariadb.com/kb/en/not-regexp/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise AND', '&', 'https://mariadb.com/kb/en/bitwise_and/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise OR', '|', 'https://mariadb.com/kb/en/bitwise-or/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise XOR', '^', 'https://mariadb.com/kb/en/bitwise-xor/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise NOT', '~', 'https://mariadb.com/kb/en/bitwise-not/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Left shift', '<<', 'https://mariadb.com/kb/en/shift-left/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Right shift', '>>', 'https://mariadb.com/kb/en/shift-right/'); + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT REGEXP', 'NOT REGEXP', 'https://mariadb.com/kb/en/not-regexp/'); INSERT INTO `mdb_ontologies` (prefix, uri, uri_pattern, sparql_endpoint, rdf_path) diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java index 35bfafdf464d0876e96924b2d98605e41ba14bda..39eb0116527395ca9dcfdf634e44b675fc46b122 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java @@ -2,6 +2,7 @@ package at.tuwien.api.container; import at.tuwien.api.CacheableDto; import at.tuwien.api.container.image.ImageDto; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; @@ -35,20 +36,14 @@ public class ContainerDto extends CacheableDto { @Schema(example = "air_quality") private String internalName; + @JsonIgnore @Schema(example = "data-db") private String host; + @JsonIgnore @Schema(example = "3306") private Integer port; - @JsonProperty("ui_host") - @Schema(example = "example.com") - private String uiHost; - - @JsonProperty("ui_port") - @Schema(example = "3306") - private Integer uiPort; - @NotNull private ImageDto image; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/CreateViewDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/CreateViewDto.java index 366845d08304881519c80f4984106626bf52a01a..9a9558470f575e07e9baf77b531911a80dac8757 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/CreateViewDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/CreateViewDto.java @@ -1,5 +1,6 @@ package at.tuwien.api.database; +import at.tuwien.api.database.query.SubsetDto; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; @@ -23,9 +24,8 @@ public class CreateViewDto { @Schema(example = "Air Quality") private String name; - @NotBlank - @Schema(example = "SELECT `id` FROM `air_quality`") - private String query; + @NotNull + private SubsetDto query; @NotNull @JsonProperty("is_public") diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java index 5ecca1bebc980e9ba7d436206fc2c9b19e059df6..0c8c85a41c54fa81bcf9a37a15fe0187df4182eb 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java @@ -1,6 +1,7 @@ package at.tuwien.api.database; import at.tuwien.api.CacheableDto; +import at.tuwien.api.container.ContainerBriefDto; import at.tuwien.api.container.ContainerDto; import at.tuwien.api.database.table.TableDto; import at.tuwien.api.identifier.IdentifierDto; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java index 7abd47121591e2ad5611c61dde9b6712df56dbc3..1e54da2978935edcb21d396ae66258e37281f785 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java @@ -30,8 +30,8 @@ public class ViewDto extends CacheableDto { @NotNull @JsonProperty("database_id") - @Schema(example = "2b5b2b03-fdd0-40d6-afe0-e5d02fd839e4") - private UUID vdbid; + @Schema(example = "fc29f89c-86a8-4020-9e36-4d954736c6cc") + private UUID databaseId; @NotBlank @Schema(example = "Air Quality") @@ -66,10 +66,6 @@ public class ViewDto extends CacheableDto { @Schema(example = "7de03e818900b6ea6d58ad0306d4a741d658c6df3d1964e89ed2395d8c7e7916") private String queryHash; - @ToString.Exclude - @EqualsAndHashCode.Exclude - private DatabaseDto database; - @NotNull private UserBriefDto owner; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterDto.java new file mode 100644 index 0000000000000000000000000000000000000000..3fe8744661c4308d7403b950a15bfed104d9e5a1 --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterDto.java @@ -0,0 +1,39 @@ +package at.tuwien.api.database.query; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +@Getter +@Setter +@Builder +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +@Jacksonized +@ToString +public class FilterDto { + + @NotNull + @Schema(example = "where") + private FilterTypeDto type; + + @NotNull + @JsonProperty("column_id") + @Schema(example = "14128033-54b5-4818-a489-21b0dded86e2") + private UUID columnId; + + @NotNull + @JsonProperty("operator_id") + @Schema(example = "67c5b54d-2eb0-4f42-8dc1-a504562e9f32") + private UUID operatorId; + + @NotNull + @Schema(example = "1") + private String value; + +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterTypeDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterTypeDto.java new file mode 100644 index 0000000000000000000000000000000000000000..eb9c12f7b2a19c85a79de149e356d4e362037daf --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/FilterTypeDto.java @@ -0,0 +1,28 @@ +package at.tuwien.api.database.query; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema +public enum FilterTypeDto { + + @JsonProperty("where") + WHERE("where"), + + @JsonProperty("or") + OR("or"), + + @JsonProperty("and") + AND("and"); + + private String name; + + FilterTypeDto(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderDto.java new file mode 100644 index 0000000000000000000000000000000000000000..bb58ad483145927ee0f12fd60d553123228f488d --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderDto.java @@ -0,0 +1,29 @@ +package at.tuwien.api.database.query; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import lombok.extern.jackson.Jacksonized; + +import java.util.UUID; + +@Getter +@Setter +@Builder +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +@Jacksonized +@ToString +public class OrderDto { + + @NotNull + @JsonProperty("column_id") + @Schema(example = "e891ba86-0258-41a6-a8d9-ff58bc10b618") + private UUID columnId; + + @Schema(example = "asc") + private OrderTypeDto direction; + +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderTypeDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderTypeDto.java new file mode 100644 index 0000000000000000000000000000000000000000..ee05a75e47995ef1153a0d8517430cb103cbcc34 --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/OrderTypeDto.java @@ -0,0 +1,25 @@ +package at.tuwien.api.database.query; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema +public enum OrderTypeDto { + + @JsonProperty("asc") + ASC("asc"), + + @JsonProperty("desc") + DESC("desc"); + + private String name; + + OrderTypeDto(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java index 3b0f17086aaadb9ec5c91b2c0e54f9f207811056..24915a3dd5f4cbe82dd93744d214b2488b99acd5 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java @@ -1,5 +1,6 @@ package at.tuwien.api.database.query; +import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.identifier.IdentifierBriefDto; import at.tuwien.api.user.UserBriefDto; import com.fasterxml.jackson.annotation.JsonFormat; @@ -30,7 +31,7 @@ public class QueryDto { @NotNull @JsonProperty("database_id") - @Schema(example = "1a6fb0c0-49c3-4a22-a515-35f7a3dd8e62") + @Schema(example = "fc29f89c-86a8-4020-9e36-4d954736c6cc") private UUID databaseId; @NotNull diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/SubsetDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/SubsetDto.java new file mode 100644 index 0000000000000000000000000000000000000000..6e8c238417a7d81d65a08b639fb3ddcd9b1750df --- /dev/null +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/SubsetDto.java @@ -0,0 +1,35 @@ +package at.tuwien.api.database.query; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; +import java.util.UUID; + +@Getter +@Setter +@Builder +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +@Jacksonized +@ToString +public class SubsetDto { + + @NotNull + @JsonProperty("table_id") + @Schema(example = "f7df2a7d-4ade-4c78-97b0-7c744d0893c7") + private UUID tableId; + + @NotNull + @Schema(example = "[\"e891ba86-0258-41a6-a8d9-ff58bc10b618\"]") + private List<UUID> columns; + + private List<FilterDto> filter; + + private List<OrderDto> order; + +} diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java index 3104794394e360ae23ebc82ab29364654b2ee992..3dde7091830b02f226a0526885986c264e93704d 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java @@ -2,6 +2,7 @@ package at.tuwien.api.database.table; import at.tuwien.api.CacheableDto; import at.tuwien.api.container.ContainerDto; +import at.tuwien.api.database.DatabaseBriefDto; import at.tuwien.api.database.DatabaseDto; import at.tuwien.api.database.table.columns.ColumnDto; import at.tuwien.api.database.table.constraints.ConstraintsDto; @@ -36,8 +37,8 @@ public class TableDto extends CacheableDto { @NotNull @JsonProperty("database_id") - @Schema(example = "692511b6-5af3-4043-8b9b-626af8756d92") - private UUID tdbid; + @Schema(example = "fc29f89c-86a8-4020-9e36-4d954736c6cc") + private UUID databaseId; @NotBlank @Schema(example = "Air Quality") @@ -108,10 +109,6 @@ public class TableDto extends CacheableDto { @NotNull private List<ColumnDto> columns; - @ToString.Exclude - @EqualsAndHashCode.Exclude - private DatabaseDto database; - @NotNull private ConstraintsDto constraints; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/CreateTableColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/CreateTableColumnDto.java index ca7f3b8d58a3ee08a342b6df0452719c786b863b..9733f64a163fcede451627fbbe2fc6a9b8df405d 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/CreateTableColumnDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/CreateTableColumnDto.java @@ -28,7 +28,7 @@ public class CreateTableColumnDto { private Long indexLength; @NotNull - @Schema(example = "string") + @Schema(example = "varchar") private ColumnTypeDto type; @Schema(example = "255") diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/EnumDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/EnumDto.java index 1922dc308bc55b2005edbb10a5ada79b2979a3cd..9038648513bb949a99895070cfcedf6e96260bbb 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/EnumDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/EnumDto.java @@ -18,7 +18,7 @@ import java.util.UUID; public class EnumDto { @NotNull - @Schema(example = "1") + @Schema(example = "5343bb3d-14d3-4eb7-a86f-b8fc553cb315") private UUID id; @NotNull diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/SetDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/SetDto.java index 763968e8f5eba57db1d309ab1f3ee7627f1c921a..6986212592d56a16633fc41b0b7ce4b28257bc97 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/SetDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/SetDto.java @@ -18,7 +18,7 @@ import java.util.UUID; public class SetDto { @NotNull - @Schema(example = "1") + @Schema(example = "7eb4eded-bacc-4a91-84db-a9ae6ddafda7") private UUID id; @NotNull diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/foreign/CreateForeignKeyDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/foreign/CreateForeignKeyDto.java index 31e43b0c6a4377b59d096f5acf5b6bf43067a295..5e1d0a9f86c8055c69d5c4c03ac8f7c06aec6206 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/foreign/CreateForeignKeyDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/foreign/CreateForeignKeyDto.java @@ -1,6 +1,7 @@ package at.tuwien.api.database.table.constraints.foreign; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.*; import lombok.extern.jackson.Jacksonized; @@ -17,19 +18,24 @@ import java.util.List; public class CreateForeignKeyDto { @NotNull + @Schema(example = "[\"id\"]") private List<String> columns; @NotNull + @Schema(example = "sensor") @JsonProperty("referenced_table") private String referencedTable; @NotNull + @Schema(example = "[\"other_id\"]") @JsonProperty("referenced_columns") private List<String> referencedColumns; + @Schema(example = "cascade") @JsonProperty("on_update") private ReferenceTypeDto onUpdate; + @Schema(example = "cascade") @JsonProperty("on_delete") private ReferenceTypeDto onDelete; } diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java index 43e32b8ae083ee154f221e0667ad3a2e10706071..0434d1b21fe85c60b0596507e65e1bb7a67b3be9 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java @@ -25,7 +25,7 @@ public class IdentifierBriefDto { @NotNull @JsonProperty("database_id") - @Schema(example = "1") + @Schema(example = "fc29f89c-86a8-4020-9e36-4d954736c6cc") private UUID databaseId; @JsonProperty("query_id") diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java index d2443c79850e187d54e401b0c2ebbcf787180d94..8f84a8f066d577e6ba009f6ffbc4ff144d671fc8 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java @@ -25,7 +25,9 @@ import java.util.UUID; @NoArgsConstructor @EqualsAndHashCode @EntityListeners(AuditingEntityListener.class) -@Table(name = "mdb_view") +@Table(name = "mdb_view", uniqueConstraints = { + @UniqueConstraint(columnNames = {"vdbid", "internalName"}) +}) @NamedQueries({ @NamedQuery(name = "View.findAllPublicByDatabaseId", query = "select v from View v where v.database.id = ?1 and v.isPublic = true"), @NamedQuery(name = "View.findAllPublicOrMineByDatabaseId", query = "select v from View v where v.database.id = ?1 and (v.isPublic = true or v.ownedBy = ?2)"), diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml index d294d8583b08b34fc56c835c08bac25229a6a9b7..dec6e42b20ea0aa7c7c26d5ef3e08ff24f08c9fa 100644 --- a/dbrepo-metadata-service/pom.xml +++ b/dbrepo-metadata-service/pom.xml @@ -8,6 +8,11 @@ <version>3.3.5</version> </parent> + <organization> + <name>TU Wien</name> + <url>https://www.tuwien.ac.at</url> + </organization> + <groupId>at.tuwien</groupId> <artifactId>dbrepo-metadata-service</artifactId> <name>dbrepo-metadata-service</name> @@ -60,8 +65,10 @@ <aws-s3.version>2.25.23</aws-s3.version> <jackson.version>2.15.2</jackson.version> <minio.version>8.5.7</minio.version> - <sonar.coverage.jacoco.xmlReportPaths>./report/target/site/jacoco-aggregate/jacoco.xml + <sonar.coverage.jacoco.xmlReportPaths> + ./report/target/site/jacoco-aggregate/jacoco.xml </sonar.coverage.jacoco.xmlReportPaths> + <CodeCacheSize>128m</CodeCacheSize> </properties> <dependencies> @@ -308,8 +315,25 @@ </goals> </execution> </executions> + </plugin><!-- Surefire runs all Java tests --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <!-- Note config is repeated in scalatest config --> + <configuration> + <argLine>@{argLine} -ea -Xmx4g -Xss4m -XX:MaxMetaspaceSize=2g -XX:ReservedCodeCacheSize=${CodeCacheSize} + </argLine> + </configuration> </plugin> </plugins> </build> + <licenses> + <license> + <name>Apache-2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.html</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/ViewExistsException.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/ViewExistsException.java new file mode 100644 index 0000000000000000000000000000000000000000..265974db55184f6f770190068c79596b39281b6d --- /dev/null +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/exception/ViewExistsException.java @@ -0,0 +1,21 @@ +package at.tuwien.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.CONFLICT, reason = "error.view.exists") +public class ViewExistsException extends Exception { + + public ViewExistsException(String msg) { + super(msg); + } + + public ViewExistsException(String msg, Throwable thr) { + super(msg + ": " + thr.getLocalizedMessage(), thr); + } + + public ViewExistsException(Throwable thr) { + super(thr); + } + +} diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java index 88eef556226f474c49d8aa9d4c3509a96b273f86..2d18ca0c49124539a6b9aa6072396aa247eb8167 100644 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/MetadataMapper.java @@ -563,17 +563,13 @@ public interface MetadataMapper { .name(data.getName()) .internalName(data.getInternalName()) .owner(userToUserBriefDto(data.getOwner())) - .tdbid(data.getTdbid()) + .databaseId(data.getTdbid()) .isPublic(data.getIsPublic()) .isSchemaPublic(data.getIsSchemaPublic()) .isVersioned(true) .description(data.getDescription()) .identifiers(new LinkedList<>()) .columns(new LinkedList<>()) - .database(databaseToDatabaseDto(data.getDatabase() - .toBuilder() - .tables(null) - .build())) .constraints(constraintsToConstraintsDto(data.getConstraints())) .build(); if (data.getIdentifiers() != null) { @@ -600,15 +596,15 @@ public interface MetadataMapper { table.getConstraints() .getForeignKeys() .forEach(fk -> { - fk.getTable().setDatabaseId(table.getTdbid()); - fk.getReferencedTable().setDatabaseId(table.getTdbid()); + fk.getTable().setDatabaseId(table.getDatabaseId()); + fk.getReferencedTable().setDatabaseId(table.getDatabaseId()); fk.getReferences() .forEach(ref -> { ref.setForeignKey(foreignKeyDtoToForeignKeyBriefDto(fk)); ref.getColumn().setTableId(table.getId()); - ref.getColumn().setDatabaseId(table.getTdbid()); + ref.getColumn().setDatabaseId(table.getDatabaseId()); ref.getReferencedColumn().setTableId(fk.getReferencedTable().getId()); - ref.getReferencedColumn().setDatabaseId(table.getTdbid()); + ref.getReferencedColumn().setDatabaseId(table.getDatabaseId()); }); }); table.getConstraints() @@ -823,9 +819,7 @@ public interface MetadataMapper { } @Mappings({ - @Mapping(target = "vdbid", source = "database.id"), - @Mapping(target = "database.views", ignore = true), - @Mapping(target = "database.tables", ignore = true) + @Mapping(target = "databaseId", source = "database.id") }) ViewDto viewToViewDto(View data); @@ -834,6 +828,9 @@ public interface MetadataMapper { }) ViewColumnDto viewColumnToViewColumnDto(ViewColumn data); + @Mappings({ + @Mapping(target = "vdbid", source = "database.id") + }) ViewBriefDto viewToViewBriefDto(View data); @Mappings({ diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index de510dd9702e0051db2a103342c2d18a7153d2be..d711f11a0480425dad5b760ee848a38e0793eaa6 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -520,14 +520,14 @@ public class DatabaseEndpoint extends AbstractEndpoint { .size(); database.setTables(database.getTables() .stream() - .filter(t -> t.getIsPublic() || t.getIsSchemaPublic() || optional.isPresent()) + .filter(t -> t.getIsPublic() || t.getIsSchemaPublic() || optional.isPresent() || isSystem(principal)) .toList()); log.trace("filtered database tables from {} to {}", tables, database.getTables().size()); final int views = database.getViews() .size(); database.setViews(database.getViews() .stream() - .filter(v -> v.getIsPublic() || v.getIsSchemaPublic() || optional.isPresent()) + .filter(v -> v.getIsPublic() || v.getIsSchemaPublic() || optional.isPresent() || isSystem(principal)) .toList()); log.trace("filtered database views from {} to {}", views, database.getViews().size()); if (!isSystem(principal) && !database.getOwner().getId().equals(getId(principal))) { diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index 2f3d38b64cac96b80f2b250973c2f7dfd65c4990..f04f66eb8e5c3d7527e84abcb0ef1861cb02dc42 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -17,7 +17,6 @@ import at.tuwien.service.*; import at.tuwien.validation.EndpointValidator; import io.micrometer.observation.annotation.Observed; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -28,7 +27,6 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -442,9 +440,6 @@ public class TableEndpoint extends AbstractEndpoint { @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Find table successfully", - headers = {@Header(name = "X-Username", description = "The authentication username", schema = @Schema(implementation = String.class)), - @Header(name = "X-Password", description = "The authentication password", schema = @Schema(implementation = String.class)), - @Header(name = "Access-Control-Expose-Headers", description = "Expose custom headers", schema = @Schema(implementation = String.class))}, content = {@Content( mediaType = "application/json", schema = @Schema(implementation = TableDto.class))}), @@ -486,17 +481,7 @@ public class TableEndpoint extends AbstractEndpoint { table.setConstraints(null); } final TableDto dto = metadataMapper.tableToTableDto(table); - final HttpHeaders headers = new HttpHeaders(); - if (isSystem(principal)) { - headers.set("X-Username", table.getDatabase().getContainer().getPrivilegedUsername()); - headers.set("X-Password", table.getDatabase().getContainer().getPrivilegedPassword()); - headers.set("X-Jdbc-Method", table.getDatabase().getContainer().getImage().getJdbcMethod()); - headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Jdbc-Method"); - } else { - removeInternalData(dto.getDatabase().getContainer()); - } return ResponseEntity.ok() - .headers(headers) .body(dto); } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 2214343ee67ae5e8c0d1acca7857e08cb08f275b..432b84d50f125895287516e0e628110e207f1a83 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -1,7 +1,7 @@ package at.tuwien.endpoints; -import at.tuwien.api.database.ViewBriefDto; import at.tuwien.api.database.CreateViewDto; +import at.tuwien.api.database.ViewBriefDto; import at.tuwien.api.database.ViewDto; import at.tuwien.api.database.ViewUpdateDto; import at.tuwien.api.error.ApiErrorDto; @@ -15,7 +15,6 @@ import at.tuwien.service.UserService; import at.tuwien.service.ViewService; import io.micrometer.observation.annotation.Observed; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -26,7 +25,6 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -121,6 +119,11 @@ public class ViewEndpoint extends AbstractEndpoint { content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ApiErrorDto.class))}), + @ApiResponse(responseCode = "409", + description = "View exists with name", + content = {@Content( + mediaType = "application/json", + schema = @Schema(implementation = ApiErrorDto.class))}), @ApiResponse(responseCode = "423", description = "Create view resulted in an invalid query statement", content = {@Content( @@ -141,13 +144,18 @@ public class ViewEndpoint extends AbstractEndpoint { @NotNull @Valid @RequestBody CreateViewDto data, @NotNull Principal principal) throws NotAllowedException, MalformedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, - UserNotFoundException, SearchServiceException, SearchServiceConnectionException { + UserNotFoundException, SearchServiceException, SearchServiceConnectionException, TableNotFoundException, + ImageNotFoundException, ViewExistsException { log.debug("endpoint create view, databaseId={}, data={}", databaseId, data); final Database database = databaseService.findById(databaseId); if (!database.getOwner().getId().equals(getId(principal))) { log.error("Failed to create view: not the database owner"); throw new NotAllowedException("Failed to create view: not the database owner"); } + if (database.getViews().stream().anyMatch(v -> v.getInternalName().equals(metadataMapper.nameToInternalName(data.getName())))) { + log.error("Failed to create view: name exists"); + throw new ViewExistsException("Failed to create view: name exists"); + } log.trace("create view for database {}", database); return ResponseEntity.status(HttpStatus.CREATED) .body(metadataMapper.viewToViewBriefDto( @@ -163,14 +171,6 @@ public class ViewEndpoint extends AbstractEndpoint { @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Find view successfully", - headers = {@Header(name = "X-Username", description = "The authentication username", schema = @Schema(implementation = String.class)), - @Header(name = "X-Password", description = "The authentication password", schema = @Schema(implementation = String.class)), - @Header(name = "X-Host", description = "The database hostname", schema = @Schema(implementation = String.class)), - @Header(name = "X-Port", description = "The database port number", schema = @Schema(implementation = Integer.class)), - @Header(name = "X-Type", description = "The JDBC connection type", schema = @Schema(implementation = String.class)), - @Header(name = "X-Database", description = "The database internal name", schema = @Schema(implementation = String.class)), - @Header(name = "X-View", description = "The view internal name", schema = @Schema(implementation = String.class)), - @Header(name = "Access-Control-Expose-Headers", description = "Expose custom headers", schema = @Schema(implementation = String.class))}, content = {@Content( mediaType = "application/json", schema = @Schema(implementation = ViewDto.class))}), @@ -192,25 +192,8 @@ public class ViewEndpoint extends AbstractEndpoint { log.debug("endpoint find view, databaseId={}, viewId={}", databaseId, viewId); final Database database = databaseService.findById(databaseId); final View view = viewService.findById(database, viewId); - final HttpHeaders headers = new HttpHeaders(); - if (isSystem(principal)) { - headers.set("X-Username", database.getContainer().getPrivilegedUsername()); - headers.set("X-Password", database.getContainer().getPrivilegedPassword()); - headers.set("X-Host", database.getContainer().getHost()); - headers.set("X-Port", "" + database.getContainer().getPort()); - headers.set("X-Type", database.getContainer().getImage().getJdbcMethod()); - headers.set("X-Database", database.getInternalName()); - headers.set("X-View", view.getInternalName()); - headers.set("X-Jdbc-Method", view.getDatabase().getContainer().getImage().getJdbcMethod()); - headers.set("Access-Control-Expose-Headers", "X-Username X-Password X-Host X-Port X-Type X-Database X-View X-Jdbc-Method"); - } - final ViewDto dto = metadataMapper.viewToViewDto(view); - if (!isSystem(principal)) { - removeInternalData(dto.getDatabase().getContainer()); - } return ResponseEntity.status(HttpStatus.OK) - .headers(headers) - .body(dto); + .body(metadataMapper.viewToViewDto(view)); } @DeleteMapping("/{viewId}") diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java index aca2f9f356840af623ac0443fa6392092a5f865a..eadce489d9e2cb689012e5f9f4eaafeed0093566 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/handlers/ApiExceptionHandler.java @@ -473,6 +473,13 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler { return generic_handle(e.getClass(), e.getLocalizedMessage()); } + @Hidden + @ResponseStatus(code = HttpStatus.CONFLICT) + @ExceptionHandler(ViewExistsException.class) + public ResponseEntity<ApiErrorDto> handle(ViewExistsException e) { + return generic_handle(e.getClass(), e.getLocalizedMessage()); + } + @Hidden @ResponseStatus(code = HttpStatus.BAD_REQUEST) @ExceptionHandler(ViewMalformedException.class) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java index 9978574d156702eabe253c5b785cc56002aa0074..28117400a6d39331bfe23d689e294d077d815b53 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/DatabaseEndpointUnitTest.java @@ -563,8 +563,8 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findById_anonymousPublicSchemaNoAccess_succeeds() throws UserNotFoundException, NotAllowedException, - DataServiceException, DatabaseNotFoundException, ExchangeNotFoundException, DataServiceConnectionException { + public void findById_anonymousPublicSchemaNoAccess_succeeds() throws NotAllowedException, + DatabaseNotFoundException { /* test */ final DatabaseDto database = findById_generic(DATABASE_2_ID, DATABASE_2, null); @@ -575,13 +575,12 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_LOCAL_ADMIN_USERNAME, authorities = {"system"}) - public void findById_privateSchemaNoAccessInternalUser_succeeds() throws UserNotFoundException, - NotAllowedException, DataServiceException, DatabaseNotFoundException, ExchangeNotFoundException, - DataServiceConnectionException { + public void findById_privateSchemaNoAccessInternalUser_succeeds() throws NotAllowedException, + DatabaseNotFoundException { /* test */ final DatabaseDto database = findById_generic(DATABASE_3_ID, DATABASE_3, USER_LOCAL_ADMIN_PRINCIPAL); - assertEquals(0, database.getTables().size()); + assertEquals(1, database.getTables().size()); assertEquals(1, database.getViews().size()); assertNotEquals(0, database.getAccesses().size()); } @@ -608,8 +607,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME) - public void findById_ownerSeesAccessRights_succeeds() throws DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { + public void findById_ownerSeesAccessRights_succeeds() throws DatabaseNotFoundException, NotAllowedException { /* mock */ when(accessService.list(DATABASE_1)) @@ -624,8 +622,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_2_USERNAME) - public void findById_hiddenAccessRights_succeeds() throws DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { + public void findById_hiddenAccessRights_succeeds() throws DatabaseNotFoundException, NotAllowedException { /* mock */ when(accessService.list(DATABASE_1)) @@ -640,8 +637,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME) - public void findById_hiddenAccessRightsSeesOwn_succeeds() throws DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, ExchangeNotFoundException, UserNotFoundException, NotAllowedException { + public void findById_hiddenAccessRightsSeesOwn_succeeds() throws DatabaseNotFoundException, NotAllowedException { /* mock */ when(accessService.list(DATABASE_1)) @@ -775,8 +771,7 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { } public DatabaseDto findById_generic(UUID databaseId, Database database, Principal principal) - throws DataServiceConnectionException, DatabaseNotFoundException, ExchangeNotFoundException, - DataServiceException, UserNotFoundException, NotAllowedException { + throws DatabaseNotFoundException, NotAllowedException { /* mock */ if (database != null) { @@ -796,7 +791,8 @@ public class DatabaseEndpointUnitTest extends AbstractUnitTest { return body; } - public ResponseEntity<byte[]> findPreviewImage_generic(UUID databaseId, Database database) throws DatabaseNotFoundException { + public ResponseEntity<byte[]> findPreviewImage_generic(UUID databaseId, Database database) + throws DatabaseNotFoundException { /* mock */ if (database != null) { diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java index 092b8c563ddf2ccee2910d140638ca3ad087a6ac..fa1339d30aaaada4bdd32787892e218418c06b3d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/TableEndpointUnitTest.java @@ -524,22 +524,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser - public void findById_publicDatabasePrivateDataPrivateSchemaAnonymous_succeeds() throws UserNotFoundException, - TableNotFoundException, NotAllowedException, DataServiceException, DatabaseNotFoundException, - AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException { - - /* test */ - final ResponseEntity<TableDto> response = generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, null, null, null); - final TableDto body = response.getBody(); - assertNull(body.getConstraints()); - assertEquals(List.of(), body.getColumns()); - } - - @Test - @WithAnonymousUser - public void findById_publicDataPublicSchemaAnonymous_succeeds() throws DataServiceException, - DataServiceConnectionException, TableNotFoundException, DatabaseNotFoundException, AccessNotFoundException, - QueueNotFoundException, UserNotFoundException, NotAllowedException { + public void findById_publicDataPublicSchemaAnonymous_succeeds() throws UserNotFoundException, + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ generic_findById(DATABASE_4_ID, DATABASE_4, TABLE_9_ID, TABLE_9, null, null, null); @@ -567,9 +553,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") - public void findById_publicHasRole_succeeds() throws DataServiceException, DataServiceConnectionException, - TableNotFoundException, DatabaseNotFoundException, AccessNotFoundException, QueueNotFoundException, - UserNotFoundException, NotAllowedException { + public void findById_publicHasRole_succeeds() throws UserNotFoundException, + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ final ResponseEntity<TableDto> response = generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, USER_1_PRINCIPAL, USER_1, DATABASE_1_USER_1_READ_ACCESS); @@ -580,9 +565,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) - public void findById_publicNoRole_succeeds() throws DataServiceException, DataServiceConnectionException, - TableNotFoundException, DatabaseNotFoundException, AccessNotFoundException, QueueNotFoundException, - UserNotFoundException, NotAllowedException { + public void findById_publicNoRole_succeeds() throws UserNotFoundException, + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, USER_1_PRINCIPAL, USER_1, null); @@ -633,7 +617,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - analyseTableColumn_generic(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), null); + analyseTableColumn_generic(DATABASE_1_ID, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), null); }); } @@ -643,7 +627,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(org.springframework.security.access.AccessDeniedException.class, () -> { - analyseTableColumn_generic(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), USER_4_PRINCIPAL); + analyseTableColumn_generic(DATABASE_1_ID, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), USER_4_PRINCIPAL); }); } @@ -653,7 +637,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { DatabaseNotFoundException { /* test */ - analyseTableColumn_generic(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), USER_1_PRINCIPAL); + analyseTableColumn_generic(DATABASE_1_ID, TABLE_1_ID, TABLE_1_COLUMNS.get(0).getId(), TABLE_1_COLUMNS.get(0), USER_1_PRINCIPAL); } @Test @@ -935,8 +919,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithAnonymousUser public void findById_privateDatabasePrivateDataPublicSchemaAnonymous_fails() throws UserNotFoundException, - TableNotFoundException, NotAllowedException, DataServiceException, DatabaseNotFoundException, - AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException { + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_2_ID, TABLE_2, null, null, null); @@ -944,19 +927,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) - public void findById_privateSchemaNotOwnerNoAccess_fails() { - - /* test */ - assertThrows(NotAllowedException.class, () -> { - generic_findById(DATABASE_3_ID, DATABASE_3, TABLE_8_ID, TABLE_8, USER_4_PRINCIPAL, USER_4, null); - }); - } - - @Test - @WithMockUser(username = USER_4_USERNAME) - public void findById_publicSchemaNotOwnerNoAccess_succeeds() throws UserNotFoundException, TableNotFoundException, - NotAllowedException, DataServiceException, DatabaseNotFoundException, AccessNotFoundException, - QueueNotFoundException, DataServiceConnectionException { + public void findById_publicSchemaNotOwnerNoAccess_succeeds() throws UserNotFoundException, + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ final ResponseEntity<TableDto> response = generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_2_ID, TABLE_2, USER_4_PRINCIPAL, USER_4, null); @@ -987,9 +959,8 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_1_USERNAME, authorities = "find-table") - public void findById_privateHasRole_succeeds() throws DataServiceException, DataServiceConnectionException, - TableNotFoundException, DatabaseNotFoundException, AccessNotFoundException, QueueNotFoundException, - UserNotFoundException, NotAllowedException { + public void findById_privateHasRole_succeeds() throws UserNotFoundException, + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ final ResponseEntity<TableDto> response = generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1, USER_1_PRINCIPAL, USER_1, DATABASE_1_USER_1_READ_ACCESS); @@ -1001,8 +972,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest { @Test @WithMockUser(username = USER_4_USERNAME) public void findById_privateDatabasePrivateDataPrivateSchemaNoRole_succeeds() throws UserNotFoundException, - TableNotFoundException, NotAllowedException, DataServiceException, DatabaseNotFoundException, - AccessNotFoundException, QueueNotFoundException, DataServiceConnectionException { + TableNotFoundException, NotAllowedException, DatabaseNotFoundException, AccessNotFoundException { /* test */ generic_findById(DATABASE_1_ID, DATABASE_1, TABLE_1_ID, TABLE_1, USER_4_PRINCIPAL, USER_4, DATABASE_1_USER_4_READ_ACCESS); @@ -1149,9 +1119,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest { assertNotNull(body); } - public void analyseTableColumn_generic(UUID databaseId, Database database, UUID tableId, UUID columnId, - TableColumn tableColumn, Principal principal) - throws MalformedException, TableNotFoundException, DatabaseNotFoundException { + public void analyseTableColumn_generic(UUID databaseId, UUID tableId, UUID columnId, TableColumn tableColumn, + Principal principal) throws MalformedException, TableNotFoundException, + DatabaseNotFoundException { /* mock */ when(entityService.suggestByColumn(tableColumn)) diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java index 1fa3d599206b7c25f31b383be3efba6d8f4bdef8..ac5a8ef524fe8c4bc40c47e7b8ba0325508a7cc5 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/ViewEndpointUnitTest.java @@ -103,7 +103,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - create_generic(DATABASE_3_ID, DATABASE_3, null, null, null, null); + create_generic(DATABASE_3_ID, DATABASE_3, "View", null, null, null, null); }); } @@ -113,7 +113,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - create_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); + create_generic(DATABASE_3_ID, DATABASE_3, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, null); }); } @@ -123,7 +123,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - create_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); + create_generic(DATABASE_3_ID, DATABASE_3, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); }); } @@ -133,7 +133,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - create_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); + create_generic(DATABASE_3_ID, DATABASE_3, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, null); }); } @@ -141,10 +141,21 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { @WithMockUser(username = USER_1_USERNAME, authorities = {"create-database-view"}) public void create_succeeds() throws UserNotFoundException, SearchServiceException, MalformedException, NotAllowedException, DataServiceException, DatabaseNotFoundException, AccessNotFoundException, - SearchServiceConnectionException, DataServiceConnectionException { + SearchServiceConnectionException, DataServiceConnectionException, TableNotFoundException, + ImageNotFoundException, ViewExistsException { /* test */ - create_generic(DATABASE_1_ID, DATABASE_1, USER_1_PRINCIPAL, USER_1_ID, USER_1, DATABASE_1_USER_1_WRITE_ALL_ACCESS); + create_generic(DATABASE_1_ID, DATABASE_1, "View", USER_1_PRINCIPAL, USER_1_ID, USER_1, DATABASE_1_USER_1_WRITE_ALL_ACCESS); + } + + @Test + @WithMockUser(username = USER_1_USERNAME, authorities = {"create-database-view"}) + public void create_exists_fails() { + + /* test */ + assertThrows(ViewExistsException.class, () -> { + create_generic(DATABASE_1_ID, DATABASE_1, VIEW_1_NAME, USER_1_PRINCIPAL, USER_1_ID, USER_1, DATABASE_1_USER_1_WRITE_ALL_ACCESS); + }); } @Test @@ -174,26 +185,6 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { find_generic(DATABASE_3_ID, DATABASE_3, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); } - @Test - @WithMockUser(username = USER_2_USERNAME) - public void find_publicSystem_succeeds() throws UserNotFoundException, DatabaseNotFoundException, - AccessNotFoundException, ViewNotFoundException { - - /* test */ - final ResponseEntity<ViewDto> response = find_generic(DATABASE_3_ID, DATABASE_3, USER_LOCAL_ADMIN_PRINCIPAL, - USER_LOCAL_ADMIN_ID, null, null); - final HttpHeaders headers = response.getHeaders(); - assertEquals(List.of(CONTAINER_1_PRIVILEGED_USERNAME), headers.get("X-Username")); - assertEquals(List.of(CONTAINER_1_PRIVILEGED_PASSWORD), headers.get("X-Password")); - assertEquals(List.of(CONTAINER_1_HOST), headers.get("X-Host")); - assertEquals(List.of("" + CONTAINER_1_PORT), headers.get("X-Port")); - assertEquals(List.of(IMAGE_1_JDBC), headers.get("X-Type")); - assertEquals(List.of(DATABASE_3_INTERNALNAME), headers.get("X-Database")); - assertEquals(List.of(VIEW_5_INTERNAL_NAME), headers.get("X-View")); - assertEquals(List.of(IMAGE_1_JDBC), headers.get("X-Jdbc-Method")); - assertEquals(List.of("X-Username X-Password X-Host X-Port X-Type X-Database X-View X-Jdbc-Method"), headers.get("Access-Control-Expose-Headers")); - } - @Test @WithMockUser(username = USER_2_USERNAME) public void find_publicHasRoleHasAccess_succeeds() throws UserNotFoundException, DatabaseNotFoundException, @@ -289,7 +280,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - create_generic(DATABASE_1_ID, DATABASE_1, null, null, null, null); + create_generic(DATABASE_1_ID, DATABASE_1, "View", null, null, null, null); }); } @@ -299,7 +290,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - create_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); + create_generic(DATABASE_1_ID, DATABASE_1, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, null); }); } @@ -309,7 +300,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(NotAllowedException.class, () -> { - create_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); + create_generic(DATABASE_1_ID, DATABASE_1, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, DATABASE_2_USER_1_READ_ACCESS); }); } @@ -319,7 +310,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { /* test */ assertThrows(AccessDeniedException.class, () -> { - create_generic(DATABASE_1_ID, DATABASE_1, USER_2_PRINCIPAL, USER_2_ID, USER_2, null); + create_generic(DATABASE_1_ID, DATABASE_1, "View", USER_2_PRINCIPAL, USER_2_ID, USER_2, null); }); } @@ -478,13 +469,14 @@ public class ViewEndpointUnitTest extends AbstractUnitTest { } } - protected void create_generic(UUID databaseId, Database database, Principal principal, UUID userId, User user, - DatabaseAccess access) throws MalformedException, DataServiceException, + protected void create_generic(UUID databaseId, Database database, String viewName, Principal principal, UUID userId, + User user, DatabaseAccess access) throws MalformedException, DataServiceException, DataServiceConnectionException, NotAllowedException, UserNotFoundException, DatabaseNotFoundException, - AccessNotFoundException, SearchServiceException, SearchServiceConnectionException { + AccessNotFoundException, SearchServiceException, SearchServiceConnectionException, TableNotFoundException, + ImageNotFoundException, ViewExistsException { final CreateViewDto request = CreateViewDto.builder() - .name(VIEW_1_NAME) - .query(VIEW_1_QUERY) + .name(viewName) + .query(VIEW_1_SUBSET_DTO) .isPublic(VIEW_1_PUBLIC) .build(); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java index e47229bd0ae17c3b56a46ed60002e5f2226ae204..91194375d0b6c80af8a49cd2330929e7bc29c2e6 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/mvc/AuthenticationPrivilegedIntegrationMvcTest.java @@ -100,10 +100,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/database/" + DATABASE_1_ID).with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) - .andExpect(header().doesNotExist("X-Username")) - .andExpect(header().doesNotExist("X-Password")) - .andExpect(header().doesNotExist("X-Jdbc-Method")) - .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @@ -151,10 +147,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/database/" + DATABASE_1_ID + "/table/" + TABLE_1_ID).header("Authorization", "Bearer " + jwt.getAccessToken())) .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("X-Jdbc-Method", IMAGE_1_JDBC)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Jdbc-Method")) .andExpect(status().isOk()); } @@ -167,10 +159,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/database/" + DATABASE_1_ID + "/table/" + TABLE_1_ID).with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) - .andExpect(header().doesNotExist("X-Username")) - .andExpect(header().doesNotExist("X-Password")) - .andExpect(header().doesNotExist("X-Jdbc-Method")) - .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @@ -183,10 +171,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/database/" + DATABASE_1_ID + "/table/" + TABLE_1_ID).with(httpBasic(USER_LOCAL_ADMIN_USERNAME, USER_LOCAL_ADMIN_PASSWORD))) .andDo(print()) - .andExpect(header().string("X-Username", CONTAINER_1_PRIVILEGED_USERNAME)) - .andExpect(header().string("X-Password", CONTAINER_1_PRIVILEGED_PASSWORD)) - .andExpect(header().string("X-Jdbc-Method", IMAGE_1_JDBC)) - .andExpect(header().string("Access-Control-Expose-Headers", "X-Username X-Password X-Jdbc-Method")) .andExpect(status().isOk()); } @@ -200,10 +184,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/database/" + DATABASE_1_ID + "/view/" + VIEW_1_ID).with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) - .andExpect(header().doesNotExist("X-Username")) - .andExpect(header().doesNotExist("X-Password")) - .andExpect(header().doesNotExist("X-Jdbc-Method")) - .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } @@ -216,10 +196,6 @@ public class AuthenticationPrivilegedIntegrationMvcTest extends AbstractUnitTest /* test */ this.mockMvc.perform(get("/api/container/" + CONTAINER_1_ID).with(httpBasic(USER_1_USERNAME, USER_1_PASSWORD))) .andDo(print()) - .andExpect(header().doesNotExist("X-Username")) - .andExpect(header().doesNotExist("X-Password")) - .andExpect(header().doesNotExist("X-Jdbc-Method")) - .andExpect(header().doesNotExist("Access-Control-Expose-Headers")) .andExpect(status().isOk()); } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceUnitTest.java index 8cb5081f6d98b68971f71f2da5538ab72bd772a8..9b0b7fcb1a241e20048fb70f85fb8b209db5f10d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceUnitTest.java @@ -2,14 +2,17 @@ package at.tuwien.service; import at.tuwien.api.database.table.CreateTableDto; import at.tuwien.api.database.table.TableStatisticDto; -import at.tuwien.api.database.table.columns.CreateTableColumnDto; +import at.tuwien.api.database.table.TableUpdateDto; import at.tuwien.api.database.table.columns.ColumnStatisticDto; import at.tuwien.api.database.table.columns.ColumnTypeDto; +import at.tuwien.api.database.table.columns.CreateTableColumnDto; import at.tuwien.api.database.table.columns.concepts.ColumnSemanticsUpdateDto; import at.tuwien.api.database.table.constraints.CreateTableConstraintsDto; import at.tuwien.api.database.table.constraints.foreign.CreateForeignKeyDto; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.table.Table; +import at.tuwien.entities.database.table.columns.ColumnEnum; +import at.tuwien.entities.database.table.columns.ColumnSet; import at.tuwien.entities.database.table.columns.TableColumn; import at.tuwien.entities.database.table.columns.TableColumnType; import at.tuwien.entities.database.table.constraints.Constraints; @@ -340,6 +343,54 @@ public class TableServiceUnitTest extends AbstractUnitTest { assertEquals(0, constraints.getForeignKeys().size()); } + @Test + public void createTable_enumsSets_succeeds() throws DataServiceException, + DataServiceConnectionException, UserNotFoundException, TableNotFoundException, DatabaseNotFoundException, + TableExistsException, SearchServiceException, SearchServiceConnectionException, MalformedException, + OntologyNotFoundException, SemanticEntityNotFoundException { + final CreateTableDto request = CreateTableDto.builder() + .name("New Table") + .description("A wonderful table") + .columns(new LinkedList<>(List.of(CreateTableColumnDto.builder() + .name("sex") + .type(ColumnTypeDto.ENUM) // <<< + .enums(new LinkedList<>(List.of("male", "female", "other"))) + .build(), + CreateTableColumnDto.builder() + .name("status") + .type(ColumnTypeDto.SET) // <<< + .sets(new LinkedList<>(List.of("single", "married", "divorced", "widowed"))) + .build()))) + .constraints(CreateTableConstraintsDto.builder() + .checks(Set.of()) + .uniques(List.of()) + .foreignKeys(List.of()) + .primaryKey(Set.of()) + .build()) + .build(); + + /* mock */ + when(userService.findByUsername(USER_1_USERNAME)) + .thenReturn(USER_1); + doNothing() + .when(dataServiceGateway) + .createTable(eq(DATABASE_1_ID), any(CreateTableDto.class)); + when(databaseRepository.save(any(Database.class))) + .thenReturn(DATABASE_1); + when(searchServiceGateway.update(any(Database.class))) + .thenReturn(DATABASE_1_BRIEF_DTO); + + /* test */ + final Table response = tableService.createTable(DATABASE_1, request, USER_1_PRINCIPAL); + final TableColumn column0 = response.getColumns().get(0); + assertEquals("sex", column0.getInternalName()); + assertEquals(TableColumnType.ENUM, column0.getColumnType()); + assertEquals(List.of("male", "female", "other"), column0.getEnums().stream().map(ColumnEnum::getValue).toList()); + final TableColumn column1 = response.getColumns().get(1); + assertEquals("status", column1.getInternalName()); + assertEquals(List.of("single", "married", "divorced", "widowed"), column1.getSets().stream().map(ColumnSet::getValue).toList()); + } + @Test public void createTable_dateFormatNotFound_fails() throws DataServiceException, DataServiceConnectionException, UserNotFoundException, DatabaseNotFoundException, TableExistsException, SearchServiceException, @@ -377,6 +428,23 @@ public class TableServiceUnitTest extends AbstractUnitTest { }); } + @Test + public void updateTable_succeeds() throws DataServiceException, DataServiceConnectionException, + TableNotFoundException, DatabaseNotFoundException, SearchServiceException, + SearchServiceConnectionException { + + /* mock */ + doNothing() + .when(dataServiceGateway) + .updateTable(any(UUID.class), any(UUID.class), any(TableUpdateDto.class)); + when(searchServiceGateway.update(any(Database.class))) + .thenReturn(DATABASE_3_BRIEF_DTO); + + /* test */ + final Table response = tableService.updateTable(TABLE_8, TABLE_8_UPDATE_DTO); + assertNotNull(response.getId()); + } + @Test public void create_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException, UserNotFoundException, TableNotFoundException, DatabaseNotFoundException, TableExistsException, diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceUnitTest.java index 75fab311dd0920eff19002c5976383f6b37e4d94..e99fef1acc76dd0067b9b94233dea06c7c23b30b 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceUnitTest.java @@ -50,10 +50,11 @@ public class ViewServiceUnitTest extends AbstractUnitTest { @Test public void create_succeeds() throws MalformedException, DataServiceException, DataServiceConnectionException, - DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException { + DatabaseNotFoundException, SearchServiceException, SearchServiceConnectionException, TableNotFoundException, + ImageNotFoundException { final CreateViewDto request = CreateViewDto.builder() .name(VIEW_1_NAME) - .query(VIEW_1_QUERY) + .query(VIEW_1_SUBSET_DTO) .isPublic(VIEW_1_PUBLIC) .build(); diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/init/weather_at.sql b/dbrepo-metadata-service/rest-service/src/test/resources/init/weather_at.sql index d02e1945506e5d66bb17dd10582f81814b940ad1..35fd3f88fe38862d9723c41b3fd746d122000a31 100644 --- a/dbrepo-metadata-service/rest-service/src/test/resources/init/weather_at.sql +++ b/dbrepo-metadata-service/rest-service/src/test/resources/init/weather_at.sql @@ -1,11 +1,17 @@ CREATE -DATABASE weather_at; + DATABASE weather_at; USE -weather_at; + weather_at; CREATE TABLE weather_location ( location VARCHAR(255) PRIMARY KEY, lat DOUBLE PRECISION NULL, lng DOUBLE PRECISION NULL -) WITH SYSTEM VERSIONING COMMENT 'Weather location'; \ No newline at end of file +) WITH SYSTEM VERSIONING COMMENT 'Weather location'; + +INSERT INTO weather_location (location, lat, lng) +VALUES ('Sakhir', 26.0318979, 50.5084668), + ('Fiorano', 44.534308, 10.8551698), + ('Spielberg', 47.219672, 14.7625382), + ('Fuji', 35.3726836, 138.927587); \ No newline at end of file diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java index 35dd5fe2b6b4f54b882d20c5685c57847dfc2c1d..b056eafe1749fe10d2e9e3a6fcfbbe80f2d27152 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/AuthTokenFilter.java @@ -13,6 +13,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; @@ -52,13 +53,13 @@ public class AuthTokenFilter extends OncePerRequestFilter { filterChain.doFilter(request, response); } - public UserDetails verifyJwt(String token) throws ServletException { + public UserDetails verifyJwt(String token) throws BadCredentialsException { final KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { log.error("Failed to find RSA algorithm"); - throw new ServletException("Failed to find RSA algorithm", e); + throw new BadCredentialsException("Failed to find RSA algorithm", e); } final X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey)); final RSAPublicKey pubKey; @@ -66,7 +67,7 @@ public class AuthTokenFilter extends OncePerRequestFilter { pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509); } catch (InvalidKeySpecException e) { log.error("Provided public key is invalid"); - throw new ServletException("Provided public key is invalid", e); + throw new BadCredentialsException("Provided public key is invalid", e); } final Algorithm algorithm = Algorithm.RSA256(pubKey, null); final Verification verification = JWT.require(algorithm); diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java index d6535bad491b18744afecbe4fdc4792dfd3e7f33..27a1c271af871b6253540674e9777368afa42e4a 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/auth/BasicAuthenticationProvider.java @@ -2,11 +2,9 @@ package at.tuwien.auth; import at.tuwien.api.keycloak.TokenDto; import at.tuwien.gateway.KeycloakGateway; -import jakarta.servlet.ServletException; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -28,13 +26,9 @@ public class BasicAuthenticationProvider implements AuthenticationManager { @Override public Authentication authenticate(Authentication auth) throws AuthenticationException { - try { - final TokenDto tokenDto = keycloakGateway.obtainUserToken(auth.getName(), auth.getCredentials().toString()); - final UserDetails userDetails = authTokenFilter.verifyJwt(tokenDto.getAccessToken()); - log.debug("set basic auth principal: {}", userDetails); - return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - } catch (ServletException e) { - throw new BadCredentialsException("Failed to authenticate with authentication service", e); - } + final TokenDto tokenDto = keycloakGateway.obtainUserToken(auth.getName(), auth.getCredentials().toString()); + final UserDetails userDetails = authTokenFilter.verifyJwt(tokenDto.getAccessToken()); + log.debug("set basic auth principal: {}", userDetails); + return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); } } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java index b67ddfdbfd2d8fc51420d814b79bf8fa98c3c3d8..4eb96aeee5b025b996d2bbbaf783a625f25372e2 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java @@ -8,6 +8,7 @@ import at.tuwien.exception.UserNotFoundException; import at.tuwien.gateway.KeycloakGateway; import at.tuwien.mapper.MetadataMapper; import jakarta.ws.rs.ForbiddenException; +import jakarta.ws.rs.NotAuthorizedException; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.Response; import lombok.extern.log4j.Log4j2; @@ -17,6 +18,7 @@ import org.keycloak.admin.client.KeycloakBuilder; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.representations.idm.UserRepresentation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.stereotype.Service; import java.util.List; @@ -38,7 +40,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway { } @Override - public TokenDto obtainUserToken(String username, String password) { + public TokenDto obtainUserToken(String username, String password) throws BadCredentialsException { try (Keycloak userKeycloak = KeycloakBuilder.builder() .serverUrl(keycloakConfig.getKeycloakEndpoint()) .realm(keycloakConfig.getRealm()) @@ -50,6 +52,9 @@ public class KeycloakGatewayImpl implements KeycloakGateway { .build()) { return metadataMapper.accessTokenResponseToTokenDto(userKeycloak.tokenManager() .getAccessToken()); + } catch (NotAuthorizedException e) { + log.error("Failed to obtain user token: {}", e.getMessage()); + throw new BadCredentialsException("Failed to obtain user token", e); } } diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java index a5769ea9868f1fcc60983733c1994ee7364edff9..54c9dd80bf7ed56040a55f019ca2e6b127a20cf9 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java @@ -54,7 +54,7 @@ public interface ViewService { */ View create(Database database, User user, CreateViewDto data) throws MalformedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, SearchServiceException, - SearchServiceConnectionException; + SearchServiceConnectionException, TableNotFoundException, ImageNotFoundException; /** * @param database diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java index 7bb45d568e7ed729f7e8a2b379d7055500ccedd3..51c9832e267aac53cb02e09802839ebbdc6b151c 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java @@ -90,7 +90,7 @@ public class ViewServiceImpl implements ViewService { @Transactional public View create(Database database, User creator, CreateViewDto data) throws MalformedException, DataServiceException, DataServiceConnectionException, DatabaseNotFoundException, SearchServiceException, - SearchServiceConnectionException { + SearchServiceConnectionException, TableNotFoundException, ImageNotFoundException { /* create in metadata database */ final View view = View.builder() .database(database) @@ -99,10 +99,6 @@ public class ViewServiceImpl implements ViewService { .ownedBy(creator.getId()) .owner(creator) .identifiers(new LinkedList<>()) - .query(data.getQuery()) - .queryHash(Hashing.sha256() - .hashString(data.getQuery(), StandardCharsets.UTF_8) - .toString()) .columns(new LinkedList<>()) .isInitialView(false) .isSchemaPublic(data.getIsSchemaPublic()) @@ -117,6 +113,10 @@ public class ViewServiceImpl implements ViewService { .toList()); view.getColumns() .forEach(column -> column.setView(view)); + view.setQuery(rawView.getQuery()); + view.setQueryHash(Hashing.sha256() + .hashString(rawView.getQuery(), StandardCharsets.UTF_8) + .toString()); database.getViews() .add(view); database = databaseRepository.save(database); diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/AbstractUnitTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/AbstractUnitTest.java index f78366fe89f6c631ae29da8020af629f71c528e6..230aada37a32157fbf17cb999edb1cf00cd9a0cd 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/AbstractUnitTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/AbstractUnitTest.java @@ -56,18 +56,12 @@ public abstract class AbstractUnitTest extends BaseTest { DATABASE_1_DTO.setViews(new LinkedList<>(List.of(VIEW_1_DTO, VIEW_2_DTO, VIEW_3_DTO))); TABLE_1_DTO.setColumns(new LinkedList<>(TABLE_1_COLUMNS_DTO)); TABLE_1_DTO.setConstraints(TABLE_1_CONSTRAINTS_DTO); - TABLE_1_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); - TABLE_1_PRIVILEGED_DTO.setColumns(new LinkedList<>(TABLE_1_COLUMNS_DTO)); - TABLE_1_PRIVILEGED_DTO.setConstraints(TABLE_1_CONSTRAINTS_DTO); TABLE_2.setDatabase(DATABASE_1); TABLE_2.setColumns(new LinkedList<>(TABLE_2_COLUMNS)); TABLE_2_CONSTRAINTS.getForeignKeys().get(0).getReferences().get(0).setForeignKey(TABLE_2_CONSTRAINTS.getForeignKeys().get(0)); TABLE_2.setConstraints(TABLE_2_CONSTRAINTS); TABLE_2_DTO.setColumns(new LinkedList<>(TABLE_2_COLUMNS_DTO)); TABLE_2_DTO.setConstraints(TABLE_2_CONSTRAINTS_DTO); - TABLE_2_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); - TABLE_2_PRIVILEGED_DTO.setColumns(new LinkedList<>(TABLE_2_COLUMNS_DTO)); - TABLE_2_PRIVILEGED_DTO.setConstraints(TABLE_2_CONSTRAINTS_DTO); TABLE_3.setDatabase(DATABASE_1); TABLE_3.setColumns(new LinkedList<>(TABLE_3_COLUMNS)); TABLE_3.setConstraints(TABLE_3_CONSTRAINTS); @@ -78,19 +72,13 @@ public abstract class AbstractUnitTest extends BaseTest { TABLE_4.setConstraints(TABLE_4_CONSTRAINTS); TABLE_4_DTO.setColumns(TABLE_4_COLUMNS_DTO); TABLE_4_DTO.setConstraints(TABLE_4_CONSTRAINTS_DTO); - TABLE_4_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); - TABLE_4_PRIVILEGED_DTO.setColumns(new LinkedList<>(TABLE_4_COLUMNS_DTO)); - TABLE_4_PRIVILEGED_DTO.setConstraints(TABLE_4_CONSTRAINTS_DTO); VIEW_1.setDatabase(DATABASE_1); VIEW_1.setColumns(new LinkedList<>(VIEW_1_COLUMNS)); VIEW_1.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_3))); - VIEW_1_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); VIEW_2.setDatabase(DATABASE_1); VIEW_2.setColumns(new LinkedList<>(VIEW_2_COLUMNS)); - VIEW_2_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); VIEW_3.setDatabase(DATABASE_1); VIEW_3.setColumns(new LinkedList<>(VIEW_3_COLUMNS)); - VIEW_3_PRIVILEGED_DTO.setDatabase(DATABASE_1_PRIVILEGED_DTO); IDENTIFIER_1.setDatabase(DATABASE_1); IDENTIFIER_2.setDatabase(DATABASE_1); IDENTIFIER_3.setDatabase(DATABASE_1); @@ -98,21 +86,23 @@ public abstract class AbstractUnitTest extends BaseTest { /* DATABASE 2 */ DATABASE_2.setSubsets(new LinkedList<>()); DATABASE_2.setAccesses(new LinkedList<>(List.of(DATABASE_2_USER_2_WRITE_ALL_ACCESS, DATABASE_2_USER_3_READ_ACCESS))); - DATABASE_2_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_2_USER_2_WRITE_ALL_ACCESS_DTO, DATABASE_2_USER_3_READ_ACCESS_DTO))); - DATABASE_2_PRIVILEGED_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_2_USER_2_WRITE_ALL_ACCESS_DTO, DATABASE_2_USER_3_READ_ACCESS_DTO))); DATABASE_2.setTables(new LinkedList<>(List.of(TABLE_5, TABLE_6, TABLE_7))); VIEW_4.setColumns(new LinkedList<>(VIEW_4_COLUMNS)); DATABASE_2.setViews(new LinkedList<>(List.of(VIEW_4))); DATABASE_2.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_5))); + DATABASE_2_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_2_USER_2_WRITE_ALL_ACCESS_DTO, DATABASE_2_USER_3_READ_ACCESS_DTO))); DATABASE_2_DTO.setTables(new LinkedList<>(List.of(TABLE_5_DTO, TABLE_6_DTO, TABLE_7_DTO))); DATABASE_2_DTO.setViews(new LinkedList<>(List.of(VIEW_4_DTO))); DATABASE_2_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_5_DTO))); + DATABASE_2_PRIVILEGED_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_2_USER_2_WRITE_ALL_ACCESS_DTO, DATABASE_2_USER_3_READ_ACCESS_DTO))); + DATABASE_2_PRIVILEGED_DTO.setTables(new LinkedList<>(List.of(TABLE_5_DTO, TABLE_6_DTO, TABLE_7_DTO))); + DATABASE_2_PRIVILEGED_DTO.setViews(new LinkedList<>(List.of(VIEW_4_DTO))); + DATABASE_2_PRIVILEGED_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_5_DTO))); TABLE_5.setDatabase(DATABASE_2); TABLE_5.setColumns(new LinkedList<>(TABLE_5_COLUMNS)); TABLE_5.setConstraints(TABLE_5_CONSTRAINTS); TABLE_5_DTO.setColumns(new LinkedList<>(TABLE_5_COLUMNS_DTO)); TABLE_5_DTO.setConstraints(TABLE_5_CONSTRAINTS_DTO); - TABLE_5_PRIVILEGED_DTO.setDatabase(DATABASE_2_PRIVILEGED_DTO); TABLE_6.setDatabase(DATABASE_2); TABLE_6.setColumns(new LinkedList<>(TABLE_6_COLUMNS)); TABLE_6.setConstraints(TABLE_6_CONSTRAINTS); @@ -138,13 +128,14 @@ public abstract class AbstractUnitTest extends BaseTest { DATABASE_3_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_6_DTO))); DATABASE_3_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_3_USER_1_WRITE_ALL_ACCESS_DTO))); DATABASE_3_PRIVILEGED_DTO.setAccesses(new LinkedList<>(List.of(DATABASE_3_USER_1_WRITE_ALL_ACCESS_DTO))); + DATABASE_3_PRIVILEGED_DTO.setTables(new LinkedList<>(List.of(TABLE_8_DTO))); + DATABASE_3_PRIVILEGED_DTO.setViews(new LinkedList<>(List.of(VIEW_5_DTO))); + DATABASE_3_PRIVILEGED_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_6_DTO))); TABLE_8.setDatabase(DATABASE_3); TABLE_8.setColumns(new LinkedList<>(TABLE_8_COLUMNS)); TABLE_8.setConstraints(TABLE_8_CONSTRAINTS); TABLE_8_DTO.setColumns(new LinkedList<>(TABLE_8_COLUMNS_DTO)); TABLE_8_DTO.setConstraints(TABLE_8_CONSTRAINTS_DTO); - TABLE_8_PRIVILEGED_DTO.setColumns(new LinkedList<>(TABLE_8_COLUMNS_DTO)); - TABLE_8_PRIVILEGED_DTO.setDatabase(DATABASE_3_PRIVILEGED_DTO); VIEW_5.setDatabase(DATABASE_3); VIEW_5.setColumns(VIEW_5_COLUMNS); VIEW_5_DTO.setColumns(VIEW_5_COLUMNS_DTO); @@ -155,6 +146,8 @@ public abstract class AbstractUnitTest extends BaseTest { DATABASE_4.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_7))); DATABASE_4_DTO.setTables(new LinkedList<>(List.of(TABLE_9_DTO))); DATABASE_4_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_7_DTO))); + DATABASE_4_PRIVILEGED_DTO.setTables(new LinkedList<>(List.of(TABLE_9_DTO))); + DATABASE_4_PRIVILEGED_DTO.setIdentifiers(new LinkedList<>(List.of(IDENTIFIER_7_DTO))); TABLE_9.setDatabase(DATABASE_4); TABLE_9.setColumns(TABLE_9_COLUMNS); TABLE_9.setConstraints(TABLE_9_CONSTRAINTS); diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index b5da835fa1e471d8e5a0ccda75724ec4d9c7c6c3..35240f97536af3f05099e844135643ea4ea00b3e 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -10,8 +10,7 @@ import at.tuwien.api.container.ContainerBriefDto; import at.tuwien.api.container.ContainerDto; import at.tuwien.api.container.image.*; import at.tuwien.api.database.*; -import at.tuwien.api.database.query.QueryBriefDto; -import at.tuwien.api.database.query.QueryDto; +import at.tuwien.api.database.query.*; import at.tuwien.api.database.table.*; import at.tuwien.api.database.table.columns.*; import at.tuwien.api.database.table.columns.concepts.*; @@ -935,7 +934,7 @@ public abstract class BaseTest { .version(IMAGE_1_VERSION) .isDefault(IMAGE_1_IS_DEFAULT) .jdbcMethod(IMAGE_1_JDBC) - .operators(null) + .operators(null) /* IMAGE_1_OPERATORS_DTO */ .build(); public static final ImageBriefDto IMAGE_1_BRIEF_DTO = ImageBriefDto.builder() @@ -950,6 +949,11 @@ public abstract class BaseTest { public static final String IMAGE_1_OPERATORS_1_VALUE = "XOR"; public static final String IMAGE_1_OPERATORS_1_DOCUMENTATION = "https://mariadb.com/kb/en/xor/"; + public static final UUID IMAGE_1_OPERATORS_2_ID = UUID.fromString("42a56348-38bd-4aba-b0f2-ac813d5d2da2"); + public static final String IMAGE_1_OPERATORS_2_DISPLAY_NAME = "="; + public static final String IMAGE_1_OPERATORS_2_VALUE = "="; + public static final String IMAGE_1_OPERATORS_2_DOCUMENTATION = "https://mariadb.com/kb/en/equal/"; + public static final List<Operator> IMAGE_1_OPERATORS = new LinkedList<>(List.of( Operator.builder() .id(IMAGE_1_OPERATORS_1_ID) @@ -957,6 +961,13 @@ public abstract class BaseTest { .displayName(IMAGE_1_OPERATORS_1_DISPLAY_NAME) .value(IMAGE_1_OPERATORS_1_VALUE) .documentation(IMAGE_1_OPERATORS_1_DOCUMENTATION) + .build(), + Operator.builder() + .id(IMAGE_1_OPERATORS_2_ID) + .image(IMAGE_1) + .displayName(IMAGE_1_OPERATORS_2_DISPLAY_NAME) + .value(IMAGE_1_OPERATORS_2_VALUE) + .documentation(IMAGE_1_OPERATORS_2_DOCUMENTATION) .build())); public static final List<OperatorDto> IMAGE_1_OPERATORS_DTO = new LinkedList<>(List.of( @@ -965,6 +976,12 @@ public abstract class BaseTest { .displayName(IMAGE_1_OPERATORS_1_DISPLAY_NAME) .value(IMAGE_1_OPERATORS_1_VALUE) .documentation(IMAGE_1_OPERATORS_1_DOCUMENTATION) + .build(), + OperatorDto.builder() + .id(IMAGE_1_OPERATORS_2_ID) + .displayName(IMAGE_1_OPERATORS_2_DISPLAY_NAME) + .value(IMAGE_1_OPERATORS_2_VALUE) + .documentation(IMAGE_1_OPERATORS_2_DOCUMENTATION) .build())); public static final UUID CONTAINER_1_ID = UUID.fromString("7ddb7e87-b965-43a2-9a24-4fa406d998f4"); @@ -1238,6 +1255,16 @@ public abstract class BaseTest { .lastRetrieved(Instant.now()) .build(); + public static final DatabaseBriefDto DATABASE_3_PRIVILEGED_BRIEF_DTO = DatabaseBriefDto.builder() + .id(DATABASE_3_ID) + .isPublic(DATABASE_3_PUBLIC) + .isSchemaPublic(DATABASE_3_SCHEMA_PUBLIC) + .name(DATABASE_3_NAME) + .internalName(DATABASE_3_INTERNALNAME) + .ownerId(USER_3_ID) + .identifiers(new LinkedList<>()) /* IDENTIFIER_6_DTO */ + .build(); + public static final DatabaseBriefDto DATABASE_3_BRIEF_DTO = DatabaseBriefDto.builder() .id(DATABASE_3_ID) .isPublic(DATABASE_3_PUBLIC) @@ -1494,29 +1521,6 @@ public abstract class BaseTest { public static final Instant TABLE_1_CREATED = Instant.ofEpochSecond(1677399975L) /* 2023-02-26 08:26:15 (UTC) */; public static final Instant TABLE_1_LAST_MODIFIED = Instant.ofEpochSecond(1677399975L) /* 2023-02-26 08:26:15 (UTC) */; - public static final TableDto TABLE_1_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_1_ID) - .tdbid(DATABASE_1_ID) - .internalName(TABLE_1_INTERNAL_NAME) - .isVersioned(TABLE_1_VERSIONED) - .isPublic(TABLE_1_SCHEMA_PUBLIC) - .description(TABLE_1_DESCRIPTION) - .name(TABLE_1_NAME) - .queueName(TABLE_1_QUEUE_NAME) - .routingKey(TABLE_1_ROUTING_KEY) - .identifiers(new LinkedList<>()) - .columns(new LinkedList<>() /* TABLE_1_COLUMNS_DTO */) - .constraints(null) /* TABLE_1_CONSTRAINTS_DTO */ - .owner(USER_1_BRIEF_DTO) - .isPublic(DATABASE_1_PUBLIC) - .avgRowLength(TABLE_1_AVG_ROW_LENGTH) - .numRows(TABLE_1_NUM_ROWS) - .dataLength(TABLE_1_DATA_LENGTH) - .maxDataLength(TABLE_1_MAX_DATA_LENGTH) - .lastRetrieved(Instant.now()) - .database(null) /* DATABASE_1_PRIVILEGED_DTO */ - .build(); - public static final Table TABLE_1 = Table.builder() .id(TABLE_1_ID) .tdbid(DATABASE_1_ID) @@ -1543,7 +1547,7 @@ public abstract class BaseTest { public static final TableDto TABLE_1_DTO = TableDto.builder() .id(TABLE_1_ID) - .tdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .internalName(TABLE_1_INTERNAL_NAME) .isVersioned(TABLE_1_VERSIONED) .isPublic(TABLE_1_IS_PUBLIC) @@ -1718,32 +1722,9 @@ public abstract class BaseTest { .maxDataLength(TABLE_2_MAX_DATA_LENGTH) .build(); - public static final TableDto TABLE_2_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_2_ID) - .tdbid(DATABASE_1_ID) - .internalName(TABLE_2_INTERNALNAME) - .isVersioned(TABLE_2_VERSIONED) - .isPublic(TABLE_2_IS_PUBLIC) - .isSchemaPublic(TABLE_2_SCHEMA_PUBLIC) - .description(TABLE_2_DESCRIPTION) - .name(TABLE_2_NAME) - .queueName(TABLE_2_QUEUE_NAME) - .routingKey(TABLE_2_ROUTING_KEY) - .identifiers(new LinkedList<>()) - .columns(new LinkedList<>() /* TABLE_2_COLUMNS_DTO */) - .constraints(null) /* TABLE_2_CONSTRAINTS_DTO */ - .owner(USER_2_BRIEF_DTO) - .avgRowLength(TABLE_2_AVG_ROW_LENGTH) - .numRows(TABLE_2_NUM_ROWS) - .dataLength(TABLE_2_DATA_LENGTH) - .maxDataLength(TABLE_2_MAX_DATA_LENGTH) - .lastRetrieved(Instant.now()) - .database(null) /* DATABASE_1_PRIVILEGED_DTO */ - .build(); - public static final TableDto TABLE_2_DTO = TableDto.builder() .id(TABLE_2_ID) - .tdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .internalName(TABLE_2_INTERNALNAME) .isVersioned(TABLE_2_VERSIONED) .isPublic(TABLE_2_IS_PUBLIC) @@ -1815,7 +1796,7 @@ public abstract class BaseTest { public static final TableDto TABLE_3_DTO = TableDto.builder() .id(TABLE_3_ID) - .tdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .internalName(TABLE_3_INTERNALNAME) .isVersioned(TABLE_3_VERSIONED) .isPublic(TABLE_3_IS_PUBLIC) @@ -1914,7 +1895,7 @@ public abstract class BaseTest { public static final TableDto TABLE_5_DTO = TableDto.builder() .id(TABLE_5_ID) - .tdbid(DATABASE_2_ID) + .databaseId(DATABASE_2_ID) .internalName(TABLE_5_INTERNALNAME) .isVersioned(TABLE_5_VERSIONED) .isPublic(TABLE_5_IS_PUBLIC) @@ -1928,29 +1909,6 @@ public abstract class BaseTest { .owner(USER_1_BRIEF_DTO) .build(); - public static final TableDto TABLE_5_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_5_ID) - .tdbid(DATABASE_2_ID) - .internalName(TABLE_5_INTERNALNAME) - .isVersioned(TABLE_5_VERSIONED) - .isPublic(TABLE_5_IS_PUBLIC) - .isSchemaPublic(TABLE_5_SCHEMA_PUBLIC) - .description(TABLE_5_DESCRIPTION) - .name(TABLE_5_NAME) - .queueName(TABLE_5_QUEUE_NAME) - .routingKey(TABLE_5_ROUTING_KEY) - .identifiers(new LinkedList<>()) - .columns(new LinkedList<>() /* TABLE_5_COLUMNS_DTO */) - .constraints(null) /* TABLE_5_CONSTRAINTS_DTO */ - .owner(USER_5_BRIEF_DTO) - .isPublic(DATABASE_2_PUBLIC) - .avgRowLength(TABLE_5_AVG_ROW_LENGTH) - .numRows(TABLE_5_NUM_ROWS) - .dataLength(TABLE_5_DATA_LENGTH) - .maxDataLength(TABLE_5_MAX_DATA_LENGTH) - .lastRetrieved(Instant.now()) - .build(); - public static final TableBriefDto TABLE_5_BRIEF_DTO = TableBriefDto.builder() .id(TABLE_5_ID) .databaseId(DATABASE_2_ID) @@ -1997,7 +1955,7 @@ public abstract class BaseTest { public static final TableDto TABLE_6_DTO = TableDto.builder() .id(TABLE_6_ID) - .tdbid(DATABASE_2_ID) + .databaseId(DATABASE_2_ID) .internalName(TABLE_6_INTERNALNAME) .isVersioned(TABLE_6_VERSIONED) .isPublic(TABLE_6_IS_PUBLIC) @@ -2057,7 +2015,7 @@ public abstract class BaseTest { public static final TableDto TABLE_7_DTO = TableDto.builder() .id(TABLE_7_ID) - .tdbid(DATABASE_2_ID) + .databaseId(DATABASE_2_ID) .internalName(TABLE_7_INTERNAL_NAME) .isVersioned(TABLE_7_VERSIONED) .isPublic(TABLE_7_IS_PUBLIC) @@ -2124,33 +2082,12 @@ public abstract class BaseTest { public static final TableDto TABLE_4_DTO = TableDto.builder() .id(TABLE_4_ID) - .tdbid(DATABASE_1_ID) - .internalName(TABLE_4_INTERNALNAME) - .description(TABLE_4_DESCRIPTION) - .name(TABLE_4_NAME) - .queueName(TABLE_4_QUEUE_NAME) - .routingKey(TABLE_4_ROUTING_KEY) - .columns(new LinkedList<>()) /* TABLE_4_COLUMNS_DTO */ - .constraints(null) /* TABLE_4_CONSTRAINTS_DTO */ - .isVersioned(TABLE_4_VERSIONED) - .isPublic(TABLE_4_IS_PUBLIC) - .isSchemaPublic(TABLE_4_SCHEMA_PUBLIC) - .owner(USER_1_BRIEF_DTO) - .avgRowLength(TABLE_4_AVG_ROW_LENGTH) - .numRows(TABLE_4_NUM_ROWS) - .dataLength(TABLE_4_DATA_LENGTH) - .maxDataLength(TABLE_4_MAX_DATA_LENGTH) - .build(); - - public static final TableDto TABLE_4_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_4_ID) - .tdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .internalName(TABLE_4_INTERNALNAME) .description(TABLE_4_DESCRIPTION) .name(TABLE_4_NAME) .queueName(TABLE_4_QUEUE_NAME) .routingKey(TABLE_4_ROUTING_KEY) - .database(null) /* DATABASE_1_DTO */ .columns(new LinkedList<>()) /* TABLE_4_COLUMNS_DTO */ .constraints(null) /* TABLE_4_CONSTRAINTS_DTO */ .isVersioned(TABLE_4_VERSIONED) @@ -2161,7 +2098,6 @@ public abstract class BaseTest { .numRows(TABLE_4_NUM_ROWS) .dataLength(TABLE_4_DATA_LENGTH) .maxDataLength(TABLE_4_MAX_DATA_LENGTH) - .lastRetrieved(Instant.now()) .build(); public static final TableBriefDto TABLE_4_BRIEF_DTO = TableBriefDto.builder() @@ -2292,7 +2228,7 @@ public abstract class BaseTest { public static final TableDto TABLE_8_DTO = TableDto.builder() .id(TABLE_8_ID) - .tdbid(DATABASE_3_ID) + .databaseId(DATABASE_3_ID) .internalName(TABLE_8_INTERNAL_NAME) .description(TABLE_8_DESCRIPTION) .isVersioned(TABLE_8_VERSIONED) @@ -2323,32 +2259,16 @@ public abstract class BaseTest { .ownedBy(USER_1_ID) .build(); - public static final TableDto TABLE_8_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_8_ID) - .tdbid(DATABASE_3_ID) - .internalName(TABLE_8_INTERNAL_NAME) - .description(TABLE_8_DESCRIPTION) - .isVersioned(TABLE_8_VERSIONED) - .isPublic(TABLE_8_IS_PUBLIC) - .isSchemaPublic(TABLE_8_SCHEMA_PUBLIC) - .name(TABLE_8_NAME) - .queueName(TABLE_8_QUEUE_NAME) - .columns(new LinkedList<>()) /* TABLE_8_COLUMNS_DTO */ - .owner(USER_1_BRIEF_DTO) - .isPublic(DATABASE_3_PUBLIC) - .lastRetrieved(Instant.now()) - .build(); - public static final UUID TABLE_9_ID = UUID.fromString("9314294f-04fc-4354-8b1f-2a8aeb566453"); - public static final String TABLE_9_NAME = "mfcc"; - public static final String TABLE_9_INTERNAL_NAME = "mfcc"; + public static final String TABLE_9_NAME = "Weather Location"; + public static final String TABLE_9_INTERNAL_NAME = "weather_location"; public static final Boolean TABLE_9_VERSIONED = true; public static final Boolean TABLE_9_IS_PUBLIC = false; public static final Boolean TABLE_9_SCHEMA_PUBLIC = true; public static final Boolean TABLE_9_PROCESSED_CONSTRAINTS = true; - public static final String TABLE_9_DESCRIPTION = "Hello mfcc"; + public static final String TABLE_9_DESCRIPTION = "Location"; public static final String TABLE_9_QUEUE_NAME = TABLE_9_INTERNAL_NAME; - public static final String TABLE_9_ROUTING_KEY = "dbrepo." + DATABASE_3_ID + "." + TABLE_9_ID; + public static final String TABLE_9_ROUTING_KEY = "dbrepo." + DATABASE_4_ID + "." + TABLE_9_ID; public static final Instant TABLE_9_CREATED = Instant.ofEpochSecond(1688400185L) /* 2023-02-26 08:29:35 (UTC) */; public static final Instant TABLE_9_LAST_MODIFIED = Instant.ofEpochSecond(1688400185L) /* 2023-02-26 08:29:35 (UTC) */; @@ -2373,7 +2293,7 @@ public abstract class BaseTest { public static final TableDto TABLE_9_DTO = TableDto.builder() .id(TABLE_9_ID) - .tdbid(DATABASE_4_ID) + .databaseId(DATABASE_4_ID) .internalName(TABLE_9_INTERNAL_NAME) .description(TABLE_9_DESCRIPTION) .isVersioned(TABLE_9_VERSIONED) @@ -2398,22 +2318,6 @@ public abstract class BaseTest { .ownedBy(USER_1_ID) .build(); - public static final TableDto TABLE_9_PRIVILEGED_DTO = TableDto.builder() - .id(TABLE_9_ID) - .tdbid(DATABASE_4_ID) - .internalName(TABLE_9_INTERNAL_NAME) - .description(TABLE_9_DESCRIPTION) - .isVersioned(TABLE_9_VERSIONED) - .isPublic(TABLE_9_IS_PUBLIC) - .isSchemaPublic(TABLE_9_SCHEMA_PUBLIC) - .name(TABLE_9_NAME) - .queueName(TABLE_9_QUEUE_NAME) - .columns(new LinkedList<>()) /* TABLE_9_COLUMNS_DTO */ - .owner(USER_1_BRIEF_DTO) - .isPublic(DATABASE_3_PUBLIC) - .lastRetrieved(Instant.now()) - .build(); - public static final UUID COLUMN_9_1_ID = UUID.fromString("e03c7578-2d1a-4599-9b11-7174f40efc0a"); public static final String COLUMN_9_1_NAME = "location"; public static final String COLUMN_9_1_INTERNAL_NAME = "location"; @@ -2526,6 +2430,54 @@ public abstract class BaseTest { .build()))) .build(); + public static final UUID QUERY_9_ID = UUID.fromString("df34f0b9-b64c-406c-9109-7a031f4a7f27"); + public static final String QUERY_9_STATEMENT = "SELECT `lat`, `lng` FROM `mfcc` WHERE `location` = 'Fuji'"; + public static final String QUERY_9_QUERY_HASH = "dfcdec827b2ea74d89415f8d1ce39354f59ef304444ba4e12e4f3d9d3f35abe3"; + public static final String QUERY_9_RESULT_HASH = "f0aba070a1fd29e96230d12d7c0b4d08b89820b3cc2dda0575680492010016e7"; + public static final Instant QUERY_9_CREATED = Instant.now().minus(5, MINUTES); + public static final Instant QUERY_9_EXECUTION = Instant.now().minus(1, MINUTES); + public static final Instant QUERY_9_LAST_MODIFIED = Instant.ofEpochSecond(1551588555L); + public static final Long QUERY_9_RESULT_NUMBER = 6L; + public static final Boolean QUERY_9_PERSISTED = true; + + public static final QueryDto QUERY_9_DTO = QueryDto.builder() + .id(QUERY_9_ID) + .databaseId(DATABASE_3_ID) + .query(QUERY_9_STATEMENT) + .queryNormalized(QUERY_9_STATEMENT) + .resultNumber(QUERY_9_RESULT_NUMBER) + .resultHash(QUERY_9_RESULT_HASH) + .queryHash(QUERY_9_QUERY_HASH) + .execution(QUERY_9_EXECUTION) + .isPersisted(QUERY_9_PERSISTED) + .owner(USER_1_BRIEF_DTO) + .build(); + + public static final SubsetDto QUERY_9_SUBSET_DTO = SubsetDto.builder() + .tableId(TABLE_9_ID) + .columns(new LinkedList<>(List.of(COLUMN_9_2_ID, COLUMN_9_3_ID))) + .filter(new LinkedList<>(List.of(FilterDto.builder() + .columnId(COLUMN_9_1_ID) + .operatorId(IMAGE_1_OPERATORS_2_ID) + .value("Fuji") + .type(FilterTypeDto.WHERE) + .build()))) + .build(); + + public static final ViewDto QUERY_9_VIEW_DTO = ViewDto.builder() + .query(QUERY_9_STATEMENT) + .queryHash(QUERY_9_QUERY_HASH) + .owner(USER_1_BRIEF_DTO) + .columns(new LinkedList<>(List.of(ViewColumnDto.builder() + .name("lat") + .internalName("lat") + .build(), + ViewColumnDto.builder() + .name("lng") + .internalName("lng") + .build()))) + .build(); + public static final String QUEUE_NAME = "dbrepo"; public static final String QUEUE_VHOST = "dbrepo"; public static final Boolean QUEUE_AUTO_DELETE = false; @@ -2819,20 +2771,16 @@ public abstract class BaseTest { public static final Instant QUERY_1_EXECUTION = Instant.now(); public static final Boolean QUERY_1_PERSISTED = true; - public static final QueryDto QUERY_1_DTO = QueryDto.builder() - .id(QUERY_1_ID) - .databaseId(DATABASE_1_ID) - .query(QUERY_1_STATEMENT) - .queryHash(QUERY_1_QUERY_HASH) - .resultHash(QUERY_1_RESULT_HASH) - .execution(QUERY_1_EXECUTION) - .owner(USER_1_BRIEF_DTO) - .isPersisted(QUERY_1_PERSISTED) - .resultNumber(3L) + public static final SubsetDto QUERY_1_SUBSET_DTO = SubsetDto.builder() + .tableId(TABLE_1_ID) + .columns(new LinkedList<UUID>(List.of(COLUMN_1_1_ID, COLUMN_1_2_ID, COLUMN_1_3_ID, COLUMN_1_4_ID, COLUMN_1_5_ID))) + .order(new LinkedList<OrderDto>(List.of(OrderDto.builder() + .columnId(COLUMN_1_1_ID) + .direction(OrderTypeDto.ASC) + .build()))) .build(); public static final ViewDto QUERY_1_VIEW_DTO = ViewDto.builder() - .vdbid(DATABASE_1_ID) .query(QUERY_1_STATEMENT) .queryHash(QUERY_1_QUERY_HASH) .owner(USER_1_BRIEF_DTO) @@ -2880,20 +2828,6 @@ public abstract class BaseTest { public static final Instant QUERY_2_LAST_MODIFIED = Instant.ofEpochSecond(1541588352L); public static final Boolean QUERY_2_PERSISTED = false; - public static final QueryDto QUERY_2_DTO = QueryDto.builder() - .id(QUERY_2_ID) - .databaseId(DATABASE_2_ID) - .query(QUERY_2_STATEMENT) - .queryNormalized(QUERY_2_STATEMENT) - .resultNumber(QUERY_2_RESULT_NUMBER) - .resultHash(QUERY_2_RESULT_HASH) - .owner(USER_1_BRIEF_DTO) - .queryHash(QUERY_2_QUERY_HASH) - .execution(QUERY_2_EXECUTION) - .isPersisted(QUERY_2_PERSISTED) - .resultNumber(3L) - .build(); - public static final UUID QUERY_3_ID = UUID.fromString("a9849020-45a7-40a8-9a19-d4ae2b28dd46"); public static final String QUERY_3_STATEMENT = "SELECT `location`, `mintemp` FROM `weather_aus` WHERE `mintemp` > 10"; public static final String QUERY_3_QUERY_HASH = "a3d3dd94ebc7653bb5a3b55dd8ed5e91d3d13c335c6855a1eb4eb7ca14c36ced"; @@ -2904,20 +2838,6 @@ public abstract class BaseTest { public static final Long QUERY_3_RESULT_NUMBER = 2L; public static final Boolean QUERY_3_PERSISTED = true; - public static final QueryDto QUERY_3_DTO = QueryDto.builder() - .id(QUERY_3_ID) - .databaseId(DATABASE_1_ID) - .query(QUERY_3_STATEMENT) - .queryNormalized(QUERY_3_STATEMENT) - .resultNumber(QUERY_3_RESULT_NUMBER) - .resultHash(QUERY_3_RESULT_HASH) - .owner(USER_1_BRIEF_DTO) - .queryHash(QUERY_3_QUERY_HASH) - .execution(QUERY_3_EXECUTION) - .isPersisted(QUERY_3_PERSISTED) - .resultNumber(2L) - .build(); - public static final UUID QUERY_7_ID = UUID.fromString("fe73a325-30a0-444c-b74f-23ce1533e55f"); public static final String QUERY_7_STATEMENT = "SELECT id, date, a.location, lat, lng FROM weather_aus a JOIN weather_location l on a.location = l.location WHERE date = '2008-12-01'"; public static final String QUERY_7_QUERY_HASH = "df7da3801dfb5c191ff6711d79ce6455f3c09ec8323ce1ff7208ab85387263f5"; @@ -2929,20 +2849,6 @@ public abstract class BaseTest { public static final Long QUERY_7_RESULT_ID = 4L; public static final Boolean QUERY_7_PERSISTED = false; - public static final QueryDto QUERY_7_DTO = QueryDto.builder() - .id(QUERY_7_ID) - .databaseId(DATABASE_4_ID) - .query(QUERY_7_STATEMENT) - .queryNormalized(QUERY_7_STATEMENT) - .resultNumber(QUERY_7_RESULT_NUMBER) - .resultHash(QUERY_7_RESULT_HASH) - .owner(USER_1_BRIEF_DTO) - .queryHash(QUERY_7_QUERY_HASH) - .execution(QUERY_7_EXECUTION) - .isPersisted(QUERY_7_PERSISTED) - .resultNumber(2L) - .build(); - public static final UUID QUERY_4_ID = UUID.fromString("18a98197-51ff-4011-9f40-914a11675a6d"); public static final String QUERY_4_STATEMENT = "SELECT `id`, `value` FROM `mfcc`"; public static final String QUERY_4_QUERY_HASH = "df7da3801dfb5c191ff6711d79ce6455f3c09ec8323ce1ff7208ab85387263f5"; @@ -2954,18 +2860,6 @@ public abstract class BaseTest { public static final Long QUERY_4_RESULT_ID = 4L; public static final Boolean QUERY_4_PERSISTED = false; - public static final QueryDto QUERY_4 = QueryDto.builder() - .id(QUERY_4_ID) - .query(QUERY_4_STATEMENT) - .queryHash(QUERY_4_QUERY_HASH) - .resultHash(QUERY_4_RESULT_HASH) - .execution(QUERY_4_EXECUTION) - .isPersisted(QUERY_4_PERSISTED) - .resultNumber(QUERY_4_RESULT_NUMBER) - .owner(USER_3_BRIEF_DTO) - .isPersisted(QUERY_4_PERSISTED) - .build(); - public static final List<Map<String, Object>> QUERY_4_RESULT_DTO = new LinkedList<>(List.of( new HashMap<>() {{ put("id", BigInteger.valueOf(1L)); @@ -3023,8 +2917,18 @@ public abstract class BaseTest { .owner(USER_1_BRIEF_DTO) .build(); + public static final SubsetDto QUERY_5_SUBSET_DTO = SubsetDto.builder() + .tableId(TABLE_8_ID) + .columns(new LinkedList<>(List.of(COLUMN_8_1_ID, COLUMN_8_2_ID))) + .filter(new LinkedList<>(List.of(FilterDto.builder() + .columnId(COLUMN_8_2_ID) + .operatorId(IMAGE_1_OPERATORS_2_ID) + .value("0") + .type(FilterTypeDto.WHERE) + .build()))) + .build(); + public static final ViewDto QUERY_5_VIEW_DTO = ViewDto.builder() - .vdbid(DATABASE_3_ID) .query(QUERY_5_STATEMENT) .queryHash(QUERY_5_QUERY_HASH) .owner(USER_1_BRIEF_DTO) @@ -3057,19 +2961,6 @@ public abstract class BaseTest { public static final Long QUERY_6_RESULT_NUMBER = 1L; public static final Boolean QUERY_6_PERSISTED = true; - public static final QueryDto QUERY_6_DTO = QueryDto.builder() - .id(QUERY_6_ID) - .databaseId(DATABASE_2_ID) - .query(QUERY_6_STATEMENT) - .queryNormalized(QUERY_6_STATEMENT) - .resultNumber(QUERY_6_RESULT_NUMBER) - .resultHash(QUERY_6_RESULT_HASH) - .owner(USER_1_BRIEF_DTO) - .queryHash(QUERY_6_QUERY_HASH) - .execution(QUERY_6_EXECUTION) - .isPersisted(QUERY_6_PERSISTED) - .build(); - public static final List<TableColumn> TABLE_1_COLUMNS = List.of(TableColumn.builder() .id(COLUMN_1_1_ID) .ordinalPosition(0) @@ -4739,6 +4630,34 @@ public abstract class BaseTest { .constraints(TABLE_5_CONSTRAINTS_INVALID_CREATE) .build(); + public static final UUID QUERY_8_ID = UUID.fromString("1c466eee-d551-4ef9-a7e0-b5a2d1b15473"); + public static final String QUERY_8_STATEMENT = "SELECT `id`, `animal_name` FROM `zoo` WHERE `hair` = TRUE AND `feathers` = FALSE;"; + public static final String QUERY_8_QUERY_HASH = "f0ee0d6dd45e092fca120c4f0eab089f91ed26ccf8dc34a03c6b9c6bb4141271"; + public static final Long QUERY_8_RESULT_NUMBER = 5L; + public static final String QUERY_8_RESULT_HASH = "b5f9cae916d32deff81c5f2e9f8ff43904034bc084b12320730953d120698bed"; + public static final Instant QUERY_8_EXECUTION = Instant.now().minus(1, MINUTES); + public static final Boolean QUERY_8_PERSISTED = true; + + public static final SubsetDto QUERY_8_SUBSET_DTO = SubsetDto.builder() + .tableId(TABLE_5_ID) + .columns(new LinkedList<>(List.of(COLUMN_5_1_ID, COLUMN_5_2_ID))) + .filter(new LinkedList<>(List.of(FilterDto.builder() + .type(FilterTypeDto.WHERE) + .columnId(COLUMN_5_3_ID) + .operatorId(IMAGE_1_OPERATORS_2_ID) + .value("true") + .build(), + FilterDto.builder() + .type(FilterTypeDto.AND) + .build(), + FilterDto.builder() + .type(FilterTypeDto.WHERE) + .columnId(COLUMN_5_4_ID) + .operatorId(IMAGE_1_OPERATORS_2_ID) + .value("false") + .build()))) + .build(); + public static final UUID COLUMN_6_1_ID = UUID.fromString("27b04a64-2849-4fae-b295-858c3e50361f"); public static final UUID COLUMN_6_2_ID = UUID.fromString("1ea62e32-5719-4152-94da-45d37eb88b6f"); @@ -4968,7 +4887,7 @@ public abstract class BaseTest { public static final String VIEW_1_INTERNAL_NAME = "junit"; public static final Boolean VIEW_1_PUBLIC = false; public static final Boolean VIEW_1_SCHEMA_PUBLIC = false; - public static final String VIEW_1_QUERY = "select `location`, `lat`, `lng` from `weather_location`"; + public static final String VIEW_1_QUERY = "SELECT `location`, `lat`, `lng` FROM `weather_location`"; public static final String VIEW_1_QUERY_HASH = "dc81a6877c7c51a6a6f406e1fc2a255e44a0d49a20548596e0d583c3eb849c23"; public static final UUID VIEW_COLUMN_1_1_ID = UUID.fromString("ebf2c5ce-4deb-4cc6-b6f6-61f5d3f6fc98"); @@ -4977,6 +4896,11 @@ public abstract class BaseTest { public static final UUID VIEW_COLUMN_1_3_ID = UUID.fromString("4f189a5f-c9ca-4518-9758-1a0730f6276b"); + public static final SubsetDto VIEW_1_SUBSET_DTO = SubsetDto.builder() + .tableId(TABLE_2_ID) + .columns(new LinkedList<>(List.of(COLUMN_2_1_ID, COLUMN_2_2_ID, COLUMN_2_3_ID))) + .build(); + public static final List<ViewColumnDto> VIEW_1_COLUMNS_DTO = List.of( ViewColumnDto.builder() .id(VIEW_COLUMN_1_1_ID) @@ -5084,10 +5008,10 @@ public abstract class BaseTest { public static final ViewDto VIEW_1_DTO = ViewDto.builder() .id(VIEW_1_ID) + .databaseId(DATABASE_1_ID) .isInitialView(VIEW_1_INITIAL_VIEW) .name(VIEW_1_NAME) .internalName(VIEW_1_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) .isPublic(VIEW_1_PUBLIC) .isSchemaPublic(VIEW_1_SCHEMA_PUBLIC) .identifiers(null /* VIEW_1_DTO_IDENTIFIERS */) @@ -5097,21 +5021,6 @@ public abstract class BaseTest { .columns(VIEW_1_COLUMNS_DTO) .build(); - public static final ViewDto VIEW_1_PRIVILEGED_DTO = ViewDto.builder() - .id(VIEW_1_ID) - .isInitialView(VIEW_1_INITIAL_VIEW) - .name(VIEW_1_NAME) - .internalName(VIEW_1_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) - .isPublic(VIEW_1_PUBLIC) - .owner(USER_1_BRIEF_DTO) - .query(VIEW_1_QUERY) - .queryHash(VIEW_1_QUERY_HASH) - .columns(VIEW_1_COLUMNS_DTO) - .lastRetrieved(Instant.now()) - .database(null) /* DATABASE_1_PRIVILEGED_DTO */ - .build(); - public static final ViewBriefDto VIEW_1_BRIEF_DTO = ViewBriefDto.builder() .id(VIEW_1_ID) .isInitialView(VIEW_1_INITIAL_VIEW) @@ -5128,7 +5037,7 @@ public abstract class BaseTest { public static final CreateViewDto VIEW_1_CREATE_DTO = CreateViewDto.builder() .isPublic(VIEW_1_PUBLIC) .name(VIEW_1_NAME) - .query(VIEW_1_QUERY) + .query(VIEW_1_SUBSET_DTO) .build(); public static final UUID VIEW_2_ID = UUID.fromString("1921a0a0-e4b0-4d12-a05f-be920af9b5ce"); @@ -5253,11 +5162,10 @@ public abstract class BaseTest { public static final ViewDto VIEW_2_DTO = ViewDto.builder() .id(VIEW_2_ID) - .vdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .isInitialView(VIEW_2_INITIAL_VIEW) .name(VIEW_2_NAME) .internalName(VIEW_2_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) .isPublic(VIEW_2_PUBLIC) .isSchemaPublic(VIEW_2_SCHEMA_PUBLIC) .columns(VIEW_2_COLUMNS_DTO) @@ -5266,22 +5174,6 @@ public abstract class BaseTest { .owner(USER_1_BRIEF_DTO) .build(); - public static final ViewDto VIEW_2_PRIVILEGED_DTO = ViewDto.builder() - .id(VIEW_2_ID) - .isInitialView(VIEW_2_INITIAL_VIEW) - .name(VIEW_2_NAME) - .internalName(VIEW_2_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) - .isPublic(VIEW_2_PUBLIC) - .isSchemaPublic(VIEW_2_SCHEMA_PUBLIC) - .owner(USER_2_BRIEF_DTO) - .query(VIEW_2_QUERY) - .queryHash(VIEW_2_QUERY_HASH) - .columns(VIEW_2_COLUMNS_DTO) - .lastRetrieved(Instant.now()) - .database(null) /* DATABASE_1_PRIVILEGED_DTO */ - .build(); - public static final ViewBriefDto VIEW_2_BRIEF_DTO = ViewBriefDto.builder() .id(VIEW_2_ID) .isInitialView(VIEW_2_INITIAL_VIEW) @@ -5373,22 +5265,6 @@ public abstract class BaseTest { .database(null) /* DATABASE_1 */ .build(); - public static final ViewDto VIEW_3_PRIVILEGED_DTO = ViewDto.builder() - .id(VIEW_3_ID) - .isInitialView(VIEW_3_INITIAL_VIEW) - .name(VIEW_3_NAME) - .internalName(VIEW_3_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) - .isPublic(VIEW_3_PUBLIC) - .isSchemaPublic(VIEW_3_SCHEMA_PUBLIC) - .owner(USER_1_BRIEF_DTO) - .query(VIEW_3_QUERY) - .queryHash(VIEW_3_QUERY_HASH) - .columns(VIEW_3_COLUMNS_DTO) - .lastRetrieved(Instant.now()) - .database(null) /* DATABASE_1_PRIVILEGED_DTO */ - .build(); - public static final List<ViewColumn> VIEW_3_COLUMNS = List.of( ViewColumn.builder() .id(VIEW_COLUMN_3_1_ID) @@ -5435,11 +5311,10 @@ public abstract class BaseTest { public static final ViewDto VIEW_3_DTO = ViewDto.builder() .id(VIEW_3_ID) - .vdbid(DATABASE_1_ID) + .databaseId(DATABASE_1_ID) .isInitialView(VIEW_3_INITIAL_VIEW) .name(VIEW_3_NAME) .internalName(VIEW_3_INTERNAL_NAME) - .vdbid(DATABASE_1_ID) .isPublic(VIEW_3_PUBLIC) .isSchemaPublic(VIEW_3_SCHEMA_PUBLIC) .columns(VIEW_3_COLUMNS_DTO) @@ -5642,11 +5517,10 @@ public abstract class BaseTest { public static final ViewDto VIEW_4_DTO = ViewDto.builder() .id(VIEW_4_ID) - .vdbid(DATABASE_2_ID) + .databaseId(DATABASE_2_ID) .isInitialView(VIEW_4_INITIAL_VIEW) .name(VIEW_4_NAME) .internalName(VIEW_4_INTERNAL_NAME) - .vdbid(DATABASE_2_ID) .isPublic(VIEW_4_PUBLIC) .isSchemaPublic(VIEW_4_SCHEMA_PUBLIC) .query(VIEW_4_QUERY) @@ -5848,11 +5722,10 @@ public abstract class BaseTest { public static final ViewDto VIEW_5_DTO = ViewDto.builder() .id(VIEW_5_ID) - .vdbid(DATABASE_3_ID) + .databaseId(DATABASE_3_ID) .isInitialView(VIEW_5_INITIAL_VIEW) .name(VIEW_5_NAME) .internalName(VIEW_5_INTERNAL_NAME) - .vdbid(DATABASE_3_ID) .isPublic(VIEW_5_PUBLIC) .isSchemaPublic(VIEW_5_SCHEMA_PUBLIC) .query(VIEW_5_QUERY) @@ -7687,6 +7560,16 @@ public abstract class BaseTest { .lastRetrieved(Instant.now()) .build(); + public static final DatabaseBriefDto DATABASE_2_PRIVILEGED_BRIEF_DTO = DatabaseBriefDto.builder() + .id(DATABASE_2_ID) + .isPublic(DATABASE_2_PUBLIC) + .isSchemaPublic(DATABASE_2_SCHEMA_PUBLIC) + .name(DATABASE_2_NAME) + .internalName(DATABASE_2_INTERNALNAME) + .identifiers(new LinkedList<>(List.of(IDENTIFIER_5_BRIEF_DTO))) + .ownerId(USER_2_ID) + .build(); + public static final DatabaseBriefDto DATABASE_2_BRIEF_DTO = DatabaseBriefDto.builder() .id(DATABASE_2_ID) .isPublic(DATABASE_2_PUBLIC) @@ -8321,4 +8204,85 @@ public abstract class BaseTest { .resource(new InputStreamResource(InputStream.nullInputStream())) .build(); + public static final QueryDto QUERY_1_DTO = QueryDto.builder() + .id(QUERY_1_ID) + .databaseId(DATABASE_1_ID) + .query(QUERY_1_STATEMENT) + .queryHash(QUERY_1_QUERY_HASH) + .resultHash(QUERY_1_RESULT_HASH) + .execution(QUERY_1_EXECUTION) + .owner(USER_1_BRIEF_DTO) + .isPersisted(QUERY_1_PERSISTED) + .resultNumber(3L) + .build(); + + public static final QueryDto QUERY_2_DTO = QueryDto.builder() + .id(QUERY_2_ID) + .databaseId(DATABASE_1_ID) + .query(QUERY_2_STATEMENT) + .queryNormalized(QUERY_2_STATEMENT) + .resultNumber(QUERY_2_RESULT_NUMBER) + .resultHash(QUERY_2_RESULT_HASH) + .owner(USER_1_BRIEF_DTO) + .queryHash(QUERY_2_QUERY_HASH) + .execution(QUERY_2_EXECUTION) + .isPersisted(QUERY_2_PERSISTED) + .resultNumber(3L) + .build(); + + public static final QueryDto QUERY_3_DTO = QueryDto.builder() + .id(QUERY_3_ID) + .databaseId(DATABASE_1_ID) + .query(QUERY_3_STATEMENT) + .queryNormalized(QUERY_3_STATEMENT) + .resultNumber(QUERY_3_RESULT_NUMBER) + .resultHash(QUERY_3_RESULT_HASH) + .owner(USER_1_BRIEF_DTO) + .queryHash(QUERY_3_QUERY_HASH) + .execution(QUERY_3_EXECUTION) + .isPersisted(QUERY_3_PERSISTED) + .resultNumber(2L) + .build(); + + public static final QueryDto QUERY_7_DTO = QueryDto.builder() + .id(QUERY_7_ID) + .databaseId(DATABASE_4_ID) + .query(QUERY_7_STATEMENT) + .queryNormalized(QUERY_7_STATEMENT) + .resultNumber(QUERY_7_RESULT_NUMBER) + .resultHash(QUERY_7_RESULT_HASH) + .owner(USER_1_BRIEF_DTO) + .queryHash(QUERY_7_QUERY_HASH) + .execution(QUERY_7_EXECUTION) + .isPersisted(QUERY_7_PERSISTED) + .resultNumber(2L) + .build(); + + public static final QueryDto QUERY_6_DTO = QueryDto.builder() + .id(QUERY_6_ID) + .databaseId(DATABASE_1_ID) + .query(QUERY_6_STATEMENT) + .queryNormalized(QUERY_6_STATEMENT) + .resultNumber(QUERY_6_RESULT_NUMBER) + .resultHash(QUERY_6_RESULT_HASH) + .owner(USER_1_BRIEF_DTO) + .queryHash(QUERY_6_QUERY_HASH) + .execution(QUERY_6_EXECUTION) + .isPersisted(QUERY_6_PERSISTED) + .build(); + + public static final QueryDto QUERY_8_DTO = QueryDto.builder() + .id(QUERY_8_ID) + .databaseId(DATABASE_2_ID) + .query(QUERY_8_STATEMENT) + .queryNormalized(QUERY_8_STATEMENT) + .resultNumber(QUERY_8_RESULT_NUMBER) + .resultHash(QUERY_8_RESULT_HASH) + .owner(USER_1_BRIEF_DTO) + .queryHash(QUERY_8_QUERY_HASH) + .execution(QUERY_8_EXECUTION) + .isPersisted(QUERY_8_PERSISTED) + .resultNumber(3L) + .build(); + } diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock index 4dd148a5e49ea67bed885631abe6a387c133682b..576a8b3555ac843919142c4de12b2b61a6bfa9ff 100644 --- a/dbrepo-search-service/Pipfile.lock +++ b/dbrepo-search-service/Pipfile.lock @@ -26,90 +26,90 @@ }, "aiohttp": { "hashes": [ - "sha256:0450ada317a65383b7cce9576096150fdb97396dcfe559109b403c7242faffef", - "sha256:0b5263dcede17b6b0c41ef0c3ccce847d82a7da98709e75cf7efde3e9e3b5cae", - "sha256:0d5176f310a7fe6f65608213cc74f4228e4f4ce9fd10bcb2bb6da8fc66991462", - "sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a", - "sha256:145a73850926018ec1681e734cedcf2716d6a8697d90da11284043b745c286d5", - "sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0", - "sha256:246067ba0cf5560cf42e775069c5d80a8989d14a7ded21af529a4e10e3e0f0e6", - "sha256:2c311e2f63e42c1bf86361d11e2c4a59f25d9e7aabdbdf53dc38b885c5435cdb", - "sha256:2cee3b117a8d13ab98b38d5b6bdcd040cfb4181068d05ce0c474ec9db5f3c5bb", - "sha256:2de1378f72def7dfb5dbd73d86c19eda0ea7b0a6873910cc37d57e80f10d64e1", - "sha256:30f546358dfa0953db92ba620101fefc81574f87b2346556b90b5f3ef16e55ce", - "sha256:34245498eeb9ae54c687a07ad7f160053911b5745e186afe2d0c0f2898a1ab8a", - "sha256:392432a2dde22b86f70dd4a0e9671a349446c93965f261dbaecfaf28813e5c42", - "sha256:3c0600bcc1adfaaac321422d615939ef300df81e165f6522ad096b73439c0f58", - "sha256:4016e383f91f2814e48ed61e6bda7d24c4d7f2402c75dd28f7e1027ae44ea204", - "sha256:40cd36749a1035c34ba8d8aaf221b91ca3d111532e5ccb5fa8c3703ab1b967ed", - "sha256:413ad794dccb19453e2b97c2375f2ca3cdf34dc50d18cc2693bd5aed7d16f4b9", - "sha256:4a93d28ed4b4b39e6f46fd240896c29b686b75e39cc6992692e3922ff6982b4c", - "sha256:4ee84c2a22a809c4f868153b178fe59e71423e1f3d6a8cd416134bb231fbf6d3", - "sha256:50c5c7b8aa5443304c55c262c5693b108c35a3b61ef961f1e782dd52a2f559c7", - "sha256:525410e0790aab036492eeea913858989c4cb070ff373ec3bc322d700bdf47c1", - "sha256:526c900397f3bbc2db9cb360ce9c35134c908961cdd0ac25b1ae6ffcaa2507ff", - "sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802", - "sha256:584096938a001378484aa4ee54e05dc79c7b9dd933e271c744a97b3b6f644957", - "sha256:6130459189e61baac5a88c10019b21e1f0c6d00ebc770e9ce269475650ff7f73", - "sha256:67453e603cea8e85ed566b2700efa1f6916aefbc0c9fcb2e86aaffc08ec38e78", - "sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef", - "sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e", - "sha256:74bd573dde27e58c760d9ca8615c41a57e719bff315c9adb6f2a4281a28e8798", - "sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0", - "sha256:76719dd521c20a58a6c256d058547b3a9595d1d885b830013366e27011ffe804", - "sha256:7c3623053b85b4296cd3925eeb725e386644fd5bc67250b3bb08b0f144803e7b", - "sha256:7e44eba534381dd2687be50cbd5f2daded21575242ecfdaf86bbeecbc38dae8e", - "sha256:7fe3d65279bfbee8de0fb4f8c17fc4e893eed2dba21b2f680e930cc2b09075c5", - "sha256:8340def6737118f5429a5df4e88f440746b791f8f1c4ce4ad8a595f42c980bd5", - "sha256:84ede78acde96ca57f6cf8ccb8a13fbaf569f6011b9a52f870c662d4dc8cd854", - "sha256:850ff6155371fd802a280f8d369d4e15d69434651b844bde566ce97ee2277420", - "sha256:87a2e00bf17da098d90d4145375f1d985a81605267e7f9377ff94e55c5d769eb", - "sha256:88d385b8e7f3a870146bf5ea31786ef7463e99eb59e31db56e2315535d811f55", - "sha256:8a2fb742ef378284a50766e985804bd6adb5adb5aa781100b09befdbfa757b65", - "sha256:8dc0fba9a74b471c45ca1a3cb6e6913ebfae416678d90529d188886278e7f3f6", - "sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1", - "sha256:8fd12d0f989c6099e7b0f30dc6e0d1e05499f3337461f0b2b0dadea6c64b89df", - "sha256:9060addfa4ff753b09392efe41e6af06ea5dd257829199747b9f15bfad819460", - "sha256:930ffa1925393381e1e0a9b82137fa7b34c92a019b521cf9f41263976666a0d6", - "sha256:936d8a4f0f7081327014742cd51d320296b56aa6d324461a13724ab05f4b2933", - "sha256:97fe431f2ed646a3b56142fc81d238abcbaff08548d6912acb0b19a0cadc146b", - "sha256:9bd8695be2c80b665ae3f05cb584093a1e59c35ecb7d794d1edd96e8cc9201d7", - "sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259", - "sha256:a478aa11b328983c4444dacb947d4513cb371cd323f3845e53caeda6be5589d5", - "sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0", - "sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9", - "sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9", - "sha256:a7442662afebbf7b4c6d28cb7aab9e9ce3a5df055fc4116cc7228192ad6cb484", - "sha256:aa8a8caca81c0a3e765f19c6953416c58e2f4cc1b84829af01dd1c771bb2f91f", - "sha256:ab3247d58b393bda5b1c8f31c9edece7162fc13265334217785518dd770792b8", - "sha256:b10a47e5390c4b30a0d58ee12581003be52eedd506862ab7f97da7a66805befb", - "sha256:b34508f1cd928ce915ed09682d11307ba4b37d0708d1f28e5774c07a7674cac9", - "sha256:b8d3bb96c147b39c02d3db086899679f31958c5d81c494ef0fc9ef5bb1359b3d", - "sha256:b9d45dbb3aaec05cf01525ee1a7ac72de46a8c425cb75c003acd29f76b1ffe94", - "sha256:bf4480a5438f80e0f1539e15a7eb8b5f97a26fe087e9828e2c0ec2be119a9f72", - "sha256:c160a04283c8c6f55b5bf6d4cad59bb9c5b9c9cd08903841b25f1f7109ef1259", - "sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f", - "sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9", - "sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df", - "sha256:ce1bb21fc7d753b5f8a5d5a4bae99566386b15e716ebdb410154c16c91494d7f", - "sha256:d1c031a7572f62f66f1257db37ddab4cb98bfaf9b9434a3b4840bf3560f5e788", - "sha256:d589264dbba3b16e8951b6f145d1e6b883094075283dafcab4cdd564a9e353a0", - "sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c", - "sha256:e10c440d142fa8b32cfdb194caf60ceeceb3e49807072e0dc3a8887ea80e8c16", - "sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d", - "sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250", - "sha256:e4cecdb52aaa9994fbed6b81d4568427b6002f0a91c322697a4bfcc2b2363f5a", - "sha256:e5148ca8955affdfeb864aca158ecae11030e952b25b3ae15d4e2b5ba299bad2", - "sha256:e6b2732ef3bafc759f653a98881b5b9cdef0716d98f013d376ee8dfd7285abf1", - "sha256:ea756b5a7bac046d202a9a3889b9a92219f885481d78cd318db85b15cc0b7bcf", - "sha256:edb69b9589324bdc40961cdf0657815df674f1743a8d5ad9ab56a99e4833cfdd", - "sha256:f0203433121484b32646a5f5ea93ae86f3d9559d7243f07e8c0eab5ff8e3f70e", - "sha256:f6a19bcab7fbd8f8649d6595624856635159a6527861b9cdc3447af288a00c00", - "sha256:f752e80606b132140883bb262a457c475d219d7163d996dc9072434ffb0784c4", - "sha256:f7914ab70d2ee8ab91c13e5402122edbc77821c66d2758abb53aabe87f013287" + "sha256:00c8ac69e259c60976aa2edae3f13d9991cf079aaa4d3cd5a49168ae3748dee3", + "sha256:01816f07c9cc9d80f858615b1365f8319d6a5fd079cd668cc58e15aafbc76a54", + "sha256:02876bf2f69b062584965507b07bc06903c2dc93c57a554b64e012d636952654", + "sha256:0e9eb7e5764abcb49f0e2bd8f5731849b8728efbf26d0cac8e81384c95acec3f", + "sha256:0f6b2c5b4a4d22b8fb2c92ac98e0747f5f195e8e9448bfb7404cd77e7bfa243f", + "sha256:1982c98ac62c132d2b773d50e2fcc941eb0b8bad3ec078ce7e7877c4d5a2dce7", + "sha256:1e83fb1991e9d8982b3b36aea1e7ad27ea0ce18c14d054c7a404d68b0319eebb", + "sha256:25de43bb3cf83ad83efc8295af7310219af6dbe4c543c2e74988d8e9c8a2a917", + "sha256:28a772757c9067e2aee8a6b2b425d0efaa628c264d6416d283694c3d86da7689", + "sha256:2a4a13dfbb23977a51853b419141cd0a9b9573ab8d3a1455c6e63561387b52ff", + "sha256:2a8a6bc19818ac3e5596310ace5aa50d918e1ebdcc204dc96e2f4d505d51740c", + "sha256:2eabb269dc3852537d57589b36d7f7362e57d1ece308842ef44d9830d2dc3c90", + "sha256:35cda4e07f5e058a723436c4d2b7ba2124ab4e0aa49e6325aed5896507a8a42e", + "sha256:42d689a5c0a0c357018993e471893e939f555e302313d5c61dfc566c2cad6185", + "sha256:4586a68730bd2f2b04a83e83f79d271d8ed13763f64b75920f18a3a677b9a7f0", + "sha256:47dc018b1b220c48089b5b9382fbab94db35bef2fa192995be22cbad3c5730c8", + "sha256:507ab05d90586dacb4f26a001c3abf912eb719d05635cbfad930bdbeb469b36c", + "sha256:5194143927e494616e335d074e77a5dac7cd353a04755330c9adc984ac5a628e", + "sha256:51c3ff9c7a25f3cad5c09d9aacbc5aefb9267167c4652c1eb737989b554fe278", + "sha256:55789e93c5ed71832e7fac868167276beadf9877b85697020c46e9a75471f55f", + "sha256:5724cc77f4e648362ebbb49bdecb9e2b86d9b172c68a295263fa072e679ee69d", + "sha256:5ad8f1c19fe277eeb8bc45741c6d60ddd11d705c12a4d8ee17546acff98e0802", + "sha256:5ceb81a4db2decdfa087381b5fc5847aa448244f973e5da232610304e199e7b2", + "sha256:64815c6f02e8506b10113ddbc6b196f58dbef135751cc7c32136df27b736db09", + "sha256:66047eacbc73e6fe2462b77ce39fc170ab51235caf331e735eae91c95e6a11e4", + "sha256:669dd33f028e54fe4c96576f406ebb242ba534dd3a981ce009961bf49960f117", + "sha256:684eea71ab6e8ade86b9021bb62af4bf0881f6be4e926b6b5455de74e420783a", + "sha256:6b35aab22419ba45f8fc290d0010898de7a6ad131e468ffa3922b1b0b24e9d2e", + "sha256:7104d5b3943c6351d1ad7027d90bdd0ea002903e9f610735ac99df3b81f102ee", + "sha256:718d5deb678bc4b9d575bfe83a59270861417da071ab44542d0fcb6faa686636", + "sha256:747ec46290107a490d21fe1ff4183bef8022b848cf9516970cb31de6d9460088", + "sha256:7836587eef675a17d835ec3d98a8c9acdbeb2c1d72b0556f0edf4e855a25e9c1", + "sha256:78e4dd9c34ec7b8b121854eb5342bac8b02aa03075ae8618b6210a06bbb8a115", + "sha256:7b77ee42addbb1c36d35aca55e8cc6d0958f8419e458bb70888d8c69a4ca833d", + "sha256:7c1b20a1ace54af7db1f95af85da530fe97407d9063b7aaf9ce6a32f44730778", + "sha256:7f27eec42f6c3c1df09cfc1f6786308f8b525b8efaaf6d6bd76c1f52c6511f6a", + "sha256:82c249f2bfa5ecbe4a1a7902c81c0fba52ed9ebd0176ab3047395d02ad96cfcb", + "sha256:85fa0b18558eb1427090912bd456a01f71edab0872f4e0f9e4285571941e4090", + "sha256:89ce611b1eac93ce2ade68f1470889e0173d606de20c85a012bfa24be96cf867", + "sha256:8ce789231404ca8fff7f693cdce398abf6d90fd5dae2b1847477196c243b1fbb", + "sha256:90d571c98d19a8b6e793b34aa4df4cee1e8fe2862d65cc49185a3a3d0a1a3996", + "sha256:9229d8613bd8401182868fe95688f7581673e1c18ff78855671a4b8284f47bcb", + "sha256:93a1f7d857c4fcf7cabb1178058182c789b30d85de379e04f64c15b7e88d66fb", + "sha256:967b93f21b426f23ca37329230d5bd122f25516ae2f24a9cea95a30023ff8283", + "sha256:9840be675de208d1f68f84d578eaa4d1a36eee70b16ae31ab933520c49ba1325", + "sha256:9862d077b9ffa015dbe3ce6c081bdf35135948cb89116e26667dd183550833d1", + "sha256:9b5b37c863ad5b0892cc7a4ceb1e435e5e6acd3f2f8d3e11fa56f08d3c67b820", + "sha256:9e64ca2dbea28807f8484c13f684a2f761e69ba2640ec49dacd342763cc265ef", + "sha256:9fe4eb0e7f50cdb99b26250d9328faef30b1175a5dbcfd6d0578d18456bac567", + "sha256:a01fe9f1e05025eacdd97590895e2737b9f851d0eb2e017ae9574d9a4f0b6252", + "sha256:a08ad95fcbd595803e0c4280671d808eb170a64ca3f2980dd38e7a72ed8d1fea", + "sha256:a4fe27dbbeec445e6e1291e61d61eb212ee9fed6e47998b27de71d70d3e8777d", + "sha256:a7d474c5c1f0b9405c1565fafdc4429fa7d986ccbec7ce55bc6a330f36409cad", + "sha256:a86dc177eb4c286c19d1823ac296299f59ed8106c9536d2b559f65836e0fb2c6", + "sha256:aa36c35e94ecdb478246dd60db12aba57cfcd0abcad43c927a8876f25734d496", + "sha256:ab915a57c65f7a29353c8014ac4be685c8e4a19e792a79fe133a8e101111438e", + "sha256:af55314407714fe77a68a9ccaab90fdb5deb57342585fd4a3a8102b6d4370080", + "sha256:afcb6b275c2d2ba5d8418bf30a9654fa978b4f819c2e8db6311b3525c86fe637", + "sha256:b27961d65639128336b7a7c3f0046dcc62a9443d5ef962e3c84170ac620cec47", + "sha256:b5b95787335c483cd5f29577f42bbe027a412c5431f2f80a749c80d040f7ca9f", + "sha256:b73a2b139782a07658fbf170fe4bcdf70fc597fae5ffe75e5b67674c27434a9f", + "sha256:b88aca5adbf4625e11118df45acac29616b425833c3be7a05ef63a6a4017bfdb", + "sha256:b992778d95b60a21c4d8d4a5f15aaab2bd3c3e16466a72d7f9bfd86e8cea0d4b", + "sha256:ba40b7ae0f81c7029583a338853f6607b6d83a341a3dcde8bed1ea58a3af1df9", + "sha256:baae005092e3f200de02699314ac8933ec20abf998ec0be39448f6605bce93df", + "sha256:c4bea08a6aad9195ac9b1be6b0c7e8a702a9cec57ce6b713698b4a5afa9c2e33", + "sha256:c6070bcf2173a7146bb9e4735b3c62b2accba459a6eae44deea0eb23e0035a23", + "sha256:c929f9a7249a11e4aa5c157091cfad7f49cc6b13f4eecf9b747104befd9f56f2", + "sha256:c97be90d70f7db3aa041d720bfb95f4869d6063fcdf2bb8333764d97e319b7d0", + "sha256:ce10ddfbe26ed5856d6902162f71b8fe08545380570a885b4ab56aecfdcb07f4", + "sha256:cf1f31f83d16ec344136359001c5e871915c6ab685a3d8dee38e2961b4c81730", + "sha256:d2b25b2eeb35707113b2d570cadc7c612a57f1c5d3e7bb2b13870fe284e08fc0", + "sha256:d33851d85537bbf0f6291ddc97926a754c8f041af759e0aa0230fe939168852b", + "sha256:e06cf4852ce8c4442a59bae5a3ea01162b8fcb49ab438d8548b8dc79375dad8a", + "sha256:e271beb2b1dabec5cd84eb488bdabf9758d22ad13471e9c356be07ad139b3012", + "sha256:f55d0f242c2d1fcdf802c8fabcff25a9d85550a4cf3a9cf5f2a6b5742c992839", + "sha256:f81cba651db8795f688c589dd11a4fbb834f2e59bbf9bb50908be36e416dc760", + "sha256:fa1fb1b61881c8405829c50e9cc5c875bfdbf685edf57a76817dfb50643e4a1a", + "sha256:fa48dac27f41b36735c807d1ab093a8386701bbf00eb6b89a0f69d9fa26b3671", + "sha256:fbfef0666ae9e07abfa2c54c212ac18a1f63e13e0760a769f70b5717742f3ece", + "sha256:fe7065e2215e4bba63dc00db9ae654c1ba3950a5fff691475a32f511142fcddb" ], "markers": "python_version >= '3.9'", - "version": "==3.11.12" + "version": "==3.11.13" }, "aiosignal": { "hashes": [ @@ -221,7 +221,7 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "charset-normalizer": { @@ -332,44 +332,48 @@ }, "cryptography": { "hashes": [ - "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7", - "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3", - "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183", - "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69", - "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a", - "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62", - "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911", - "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7", - "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a", - "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41", - "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83", - "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12", - "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864", - "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf", - "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c", - "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2", - "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b", - "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0", - "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4", - "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9", - "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008", - "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862", - "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009", - "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7", - "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f", - "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026", - "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f", - "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd", - "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420", - "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14", - "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00" + "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", + "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41", + "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", + "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5", + "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", + "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d", + "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", + "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", + "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", + "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", + "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", + "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", + "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", + "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", + "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", + "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", + "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562", + "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", + "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", + "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", + "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", + "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", + "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", + "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa", + "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb", + "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", + "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", + "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", + "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", + "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", + "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", + "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", + "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", + "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", + "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" ], "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", - "version": "==44.0.1" + "version": "==44.0.2" }, "dbrepo": { "hashes": [ - "sha256:779e7ee84ae91131e16100fee7143013b4c231dcd3990d418d024ff76af271e9" + "sha256:7ba35243c4ead72be2bf2a2d00a3fbbae4a9c7dabb872cca8ed1b1ce77720b5d" ], "path": "./lib/dbrepo-1.7.0.tar.gz" }, @@ -611,7 +615,7 @@ "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f" ], - "markers": "python_version < '3.14' and (platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32'))))))", + "markers": "python_version >= '3.7'", "version": "==3.1.1" }, "gunicorn": { @@ -910,7 +914,7 @@ "sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610", "sha256:f6b3dfc7661f8842babd8ea07e9897fe3d9b69a1d7e5fbb743e4160f9387833b" ], - "markers": "python_version == '3.11'", + "markers": "python_version >= '3.10'", "version": "==2.2.3" }, "opensearch-py": { @@ -1012,91 +1016,107 @@ }, "propcache": { "hashes": [ - "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", - "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", - "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", - "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", - "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", - "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", - "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", - "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", - "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", - "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", - "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", - "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", - "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", - "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", - "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", - "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", - "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae", - "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", - "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", - "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", - "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", - "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", - "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", - "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", - "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", - "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", - "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", - "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", - "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587", - "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097", - "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", - "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", - "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", - "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541", - "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", - "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", - "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", - "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d", - "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", - "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", - "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", - "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf", - "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1", - "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04", - "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", - "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", - "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb", - "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b", - "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", - "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", - "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", - "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4", - "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", - "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e", - "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", - "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", - "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", - "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", - "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", - "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", - "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", - "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", - "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", - "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681", - "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347", - "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", - "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", - "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", - "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", - "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", - "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", - "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", - "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", - "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", - "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", - "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", - "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", - "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16", - "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", - "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", - "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd", - "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212" + "sha256:02df07041e0820cacc8f739510078f2aadcfd3fc57eaeeb16d5ded85c872c89e", + "sha256:03acd9ff19021bd0567582ac88f821b66883e158274183b9e5586f678984f8fe", + "sha256:03c091bb752349402f23ee43bb2bff6bd80ccab7c9df6b88ad4322258d6960fc", + "sha256:07700939b2cbd67bfb3b76a12e1412405d71019df00ca5697ce75e5ef789d829", + "sha256:0c3e893c4464ebd751b44ae76c12c5f5c1e4f6cbd6fbf67e3783cd93ad221863", + "sha256:119e244ab40f70a98c91906d4c1f4c5f2e68bd0b14e7ab0a06922038fae8a20f", + "sha256:11ae6a8a01b8a4dc79093b5d3ca2c8a4436f5ee251a9840d7790dccbd96cb649", + "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6", + "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c", + "sha256:1c8f7d896a16da9455f882870a507567d4f58c53504dc2d4b1e1d386dfe4588a", + "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c", + "sha256:24c04f8fbf60094c531667b8207acbae54146661657a1b1be6d3ca7773b7a545", + "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e", + "sha256:26a67e5c04e3119594d8cfae517f4b9330c395df07ea65eab16f3d559b7068fe", + "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075", + "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57", + "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf", + "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d", + "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc", + "sha256:3b812b3cb6caacd072276ac0492d249f210006c57726b6484a1e1805b3cfeea0", + "sha256:3c6ec957025bf32b15cbc6b67afe233c65b30005e4c55fe5768e4bb518d712f1", + "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64", + "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340", + "sha256:4544699674faf66fb6b4473a1518ae4999c1b614f0b8297b1cef96bac25381db", + "sha256:46ed02532cb66612d42ae5c3929b5e98ae330ea0f3900bc66ec5f4862069519b", + "sha256:49ea05212a529c2caffe411e25a59308b07d6e10bf2505d77da72891f9a05641", + "sha256:4fa0e7c9c3cf7c276d4f6ab9af8adddc127d04e0fcabede315904d2ff76db626", + "sha256:507c5357a8d8b4593b97fb669c50598f4e6cccbbf77e22fa9598aba78292b4d7", + "sha256:549722908de62aa0b47a78b90531c022fa6e139f9166be634f667ff45632cc92", + "sha256:58e6d2a5a7cb3e5f166fd58e71e9a4ff504be9dc61b88167e75f835da5764d07", + "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e", + "sha256:5d62c4f6706bff5d8a52fd51fec6069bef69e7202ed481486c0bc3874912c787", + "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a", + "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810", + "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d", + "sha256:65a37714b8ad9aba5780325228598a5b16c47ba0f8aeb3dc0514701e4413d7c0", + "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b", + "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043", + "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3", + "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7", + "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d", + "sha256:6c929916cbdb540d3407c66f19f73387f43e7c12fa318a66f64ac99da601bcdf", + "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138", + "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c", + "sha256:742840d1d0438eb7ea4280f3347598f507a199a35a08294afdcc560c3739989d", + "sha256:75e872573220d1ee2305b35c9813626e620768248425f58798413e9c39741f46", + "sha256:794c3dd744fad478b6232289c866c25406ecdfc47e294618bdf1697e69bd64a6", + "sha256:7c0fdbdf6983526e269e5a8d53b7ae3622dd6998468821d660d0daf72779aefa", + "sha256:7c5f5290799a3f6539cc5e6f474c3e5c5fbeba74a5e1e5be75587746a940d51e", + "sha256:7c6e7e4f9167fddc438cd653d826f2222222564daed4116a02a184b464d3ef05", + "sha256:7cedd25e5f678f7738da38037435b340694ab34d424938041aa630d8bac42663", + "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f", + "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c", + "sha256:8526b0941ec5a40220fc4dfde76aed58808e2b309c03e9fa8e2260083ef7157f", + "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7", + "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f", + "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7", + "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9", + "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667", + "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86", + "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51", + "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0", + "sha256:9ff4e9ecb6e4b363430edf2c6e50173a63e0820e549918adef70515f87ced19a", + "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c", + "sha256:a2b9bf8c79b660d0ca1ad95e587818c30ccdb11f787657458d6f26a1ea18c568", + "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af", + "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25", + "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5", + "sha256:a94ffc66738da99232ddffcf7910e0f69e2bbe3a0802e54426dbf0714e1c2ffe", + "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf", + "sha256:b0c1a133d42c6fc1f5fbcf5c91331657a1ff822e87989bf4a6e2e39b818d0ee9", + "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf", + "sha256:bb2f144c6d98bb5cbc94adeb0447cfd4c0f991341baa68eee3f3b0c9c0e83767", + "sha256:be90c94570840939fecedf99fa72839aed70b0ced449b415c85e01ae67422c90", + "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c", + "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d", + "sha256:bf4298f366ca7e1ad1d21bbb58300a6985015909964077afd37559084590c929", + "sha256:c441c841e82c5ba7a85ad25986014be8d7849c3cfbdb6004541873505929a74e", + "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32", + "sha256:cd54895e4ae7d32f1e3dd91261df46ee7483a735017dc6f987904f194aa5fd14", + "sha256:d1323cd04d6e92150bcc79d0174ce347ed4b349d748b9358fd2e497b121e03c8", + "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b", + "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc", + "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa", + "sha256:df03cd88f95b1b99052b52b1bb92173229d7a674df0ab06d2b25765ee8404bce", + "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b", + "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e", + "sha256:e560fd75aaf3e5693b91bcaddd8b314f4d57e99aef8a6c6dc692f935cc1e6bbf", + "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9", + "sha256:ecc2920630283e0783c22e2ac94427f8cca29a04cfdf331467d4f661f4072dac", + "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f", + "sha256:ee0bd3a7b2e184e88d25c9baa6a9dc609ba25b76daae942edfb14499ac7ec374", + "sha256:ee25f1ac091def37c4b59d192bbe3a206298feeb89132a470325bf76ad122a1e", + "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d", + "sha256:f47d52fd9b2ac418c4890aad2f6d21a6b96183c98021f0a48497a904199f006e", + "sha256:f857034dc68d5ceb30fb60afb6ff2103087aea10a01b613985610e007053a121", + "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5", + "sha256:fddb8870bdb83456a489ab67c6b3040a8d5a55069aa6f72f9d872235fbc52f54" ], "markers": "python_version >= '3.9'", - "version": "==0.2.1" + "version": "==0.3.0" }, "pycparser": { "hashes": [ @@ -1238,12 +1258,12 @@ }, "pytest": { "hashes": [ - "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", - "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.4" + "version": "==8.3.5" }, "python-dateutil": { "hashes": [ @@ -1355,112 +1375,112 @@ }, "rpds-py": { "hashes": [ - "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518", - "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", - "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", - "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5", - "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", - "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543", - "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", - "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", - "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", - "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", - "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", - "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd", - "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b", - "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4", - "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99", - "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", - "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", - "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", - "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1", - "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", - "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f", - "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3", - "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca", - "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d", - "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e", - "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc", - "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea", - "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", - "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b", - "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c", - "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", - "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723", - "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e", - "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", - "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6", - "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83", - "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091", - "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1", - "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", - "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", - "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728", - "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16", - "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", - "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", - "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7", - "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", - "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730", - "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", - "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25", - "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", - "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055", - "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d", - "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", - "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", - "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", - "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", - "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f", - "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd", - "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", - "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", - "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11", - "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333", - "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", - "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", - "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b", - "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", - "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c", - "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9", - "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", - "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", - "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", - "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", - "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9", - "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c", - "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", - "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", - "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", - "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", - "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", - "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", - "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", - "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", - "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", - "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", - "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", - "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", - "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84", - "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3", - "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", - "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520", - "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831", - "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", - "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf", - "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b", - "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2", - "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3", - "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130", - "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b", - "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de", - "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", - "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d", - "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", - "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e" + "sha256:09cd7dbcb673eb60518231e02874df66ec1296c01a4fcd733875755c02014b19", + "sha256:0f3288930b947cbebe767f84cf618d2cbe0b13be476e749da0e6a009f986248c", + "sha256:0fced9fd4a07a1ded1bac7e961ddd9753dd5d8b755ba8e05acba54a21f5f1522", + "sha256:112b8774b0b4ee22368fec42749b94366bd9b536f8f74c3d4175d4395f5cbd31", + "sha256:11dd60b2ffddba85715d8a66bb39b95ddbe389ad2cfcf42c833f1bcde0878eaf", + "sha256:178f8a60fc24511c0eb756af741c476b87b610dba83270fce1e5a430204566a4", + "sha256:1b08027489ba8fedde72ddd233a5ea411b85a6ed78175f40285bd401bde7466d", + "sha256:1bf5be5ba34e19be579ae873da515a2836a2166d8d7ee43be6ff909eda42b72b", + "sha256:1ed7de3c86721b4e83ac440751329ec6a1102229aa18163f84c75b06b525ad7e", + "sha256:1eedaaccc9bb66581d4ae7c50e15856e335e57ef2734dbc5fd8ba3e2a4ab3cb6", + "sha256:243241c95174b5fb7204c04595852fe3943cc41f47aa14c3828bc18cd9d3b2d6", + "sha256:26bb3e8de93443d55e2e748e9fd87deb5f8075ca7bc0502cfc8be8687d69a2ec", + "sha256:271fa2184cf28bdded86bb6217c8e08d3a169fe0bbe9be5e8d96e8476b707122", + "sha256:28358c54fffadf0ae893f6c1050e8f8853e45df22483b7fff2f6ab6152f5d8bf", + "sha256:285019078537949cecd0190f3690a0b0125ff743d6a53dfeb7a4e6787af154f5", + "sha256:2893d778d4671ee627bac4037a075168b2673c57186fb1a57e993465dbd79a93", + "sha256:2a54027554ce9b129fc3d633c92fa33b30de9f08bc61b32c053dc9b537266fed", + "sha256:2c6ae11e6e93728d86aafc51ced98b1658a0080a7dd9417d24bfb955bb09c3c2", + "sha256:2cfa07c346a7ad07019c33fb9a63cf3acb1f5363c33bc73014e20d9fe8b01cdd", + "sha256:35d5631ce0af26318dba0ae0ac941c534453e42f569011585cb323b7774502a5", + "sha256:3614d280bf7aab0d3721b5ce0e73434acb90a2c993121b6e81a1c15c665298ac", + "sha256:3902df19540e9af4cc0c3ae75974c65d2c156b9257e91f5101a51f99136d834c", + "sha256:3aaf141d39f45322e44fc2c742e4b8b4098ead5317e5f884770c8df0c332da70", + "sha256:3d8abf7896a91fb97e7977d1aadfcc2c80415d6dc2f1d0fca5b8d0df247248f3", + "sha256:3e77febf227a1dc3220159355dba68faa13f8dca9335d97504abf428469fb18b", + "sha256:3e9212f52074fc9d72cf242a84063787ab8e21e0950d4d6709886fb62bcb91d5", + "sha256:3ee9d6f0b38efb22ad94c3b68ffebe4c47865cdf4b17f6806d6c674e1feb4246", + "sha256:4233df01a250b3984465faed12ad472f035b7cd5240ea3f7c76b7a7016084495", + "sha256:4263320ed887ed843f85beba67f8b2d1483b5947f2dc73a8b068924558bfeace", + "sha256:4ab923167cfd945abb9b51a407407cf19f5bee35001221f2911dc85ffd35ff4f", + "sha256:4caafd1a22e5eaa3732acb7672a497123354bef79a9d7ceed43387d25025e935", + "sha256:50fb62f8d8364978478b12d5f03bf028c6bc2af04082479299139dc26edf4c64", + "sha256:55ff4151cfd4bc635e51cfb1c59ac9f7196b256b12e3a57deb9e5742e65941ad", + "sha256:5b98b6c953e5c2bda51ab4d5b4f172617d462eebc7f4bfdc7c7e6b423f6da957", + "sha256:5c9ff044eb07c8468594d12602291c635da292308c8c619244e30698e7fc455a", + "sha256:5e9c206a1abc27e0588cf8b7c8246e51f1a16a103734f7750830a1ccb63f557a", + "sha256:5fb89edee2fa237584e532fbf78f0ddd1e49a47c7c8cfa153ab4849dc72a35e6", + "sha256:633462ef7e61d839171bf206551d5ab42b30b71cac8f10a64a662536e057fdef", + "sha256:66f8d2a17e5838dd6fb9be6baaba8e75ae2f5fa6b6b755d597184bfcd3cb0eba", + "sha256:6959bb9928c5c999aba4a3f5a6799d571ddc2c59ff49917ecf55be2bbb4e3722", + "sha256:698a79d295626ee292d1730bc2ef6e70a3ab135b1d79ada8fde3ed0047b65a10", + "sha256:721f9c4011b443b6e84505fc00cc7aadc9d1743f1c988e4c89353e19c4a968ee", + "sha256:72e680c1518733b73c994361e4b06441b92e973ef7d9449feec72e8ee4f713da", + "sha256:75307599f0d25bf6937248e5ac4e3bde5ea72ae6618623b86146ccc7845ed00b", + "sha256:754fba3084b70162a6b91efceee8a3f06b19e43dac3f71841662053c0584209a", + "sha256:759462b2d0aa5a04be5b3e37fb8183615f47014ae6b116e17036b131985cb731", + "sha256:7938c7b0599a05246d704b3f5e01be91a93b411d0d6cc62275f025293b8a11ce", + "sha256:7b77e07233925bd33fc0022b8537774423e4c6680b6436316c5075e79b6384f4", + "sha256:7e5413d2e2d86025e73f05510ad23dad5950ab8417b7fc6beaad99be8077138b", + "sha256:7f3240dcfa14d198dba24b8b9cb3b108c06b68d45b7babd9eefc1038fdf7e707", + "sha256:7f9682a8f71acdf59fd554b82b1c12f517118ee72c0f3944eda461606dfe7eb9", + "sha256:8d67beb6002441faef8251c45e24994de32c4c8686f7356a1f601ad7c466f7c3", + "sha256:9441af1d25aed96901f97ad83d5c3e35e6cd21a25ca5e4916c82d7dd0490a4fa", + "sha256:98b257ae1e83f81fb947a363a274c4eb66640212516becaff7bef09a5dceacaa", + "sha256:9e9f3a3ac919406bc0414bbbd76c6af99253c507150191ea79fab42fdb35982a", + "sha256:a1c66e71ecfd2a4acf0e4bd75e7a3605afa8f9b28a3b497e4ba962719df2be57", + "sha256:a1e17d8dc8e57d8e0fd21f8f0f0a5211b3fa258b2e444c2053471ef93fe25a00", + "sha256:a20cb698c4a59c534c6701b1c24a968ff2768b18ea2991f886bd8985ce17a89f", + "sha256:a970bfaf130c29a679b1d0a6e0f867483cea455ab1535fb427566a475078f27f", + "sha256:a98f510d86f689fcb486dc59e6e363af04151e5260ad1bdddb5625c10f1e95f8", + "sha256:a9d3b728f5a5873d84cba997b9d617c6090ca5721caaa691f3b1a78c60adc057", + "sha256:ad76f44f70aac3a54ceb1813ca630c53415da3a24fd93c570b2dfb4856591017", + "sha256:ae28144c1daa61366205d32abd8c90372790ff79fc60c1a8ad7fd3c8553a600e", + "sha256:b03a8d50b137ee758e4c73638b10747b7c39988eb8e6cd11abb7084266455165", + "sha256:b5a96fcac2f18e5a0a23a75cd27ce2656c66c11c127b0318e508aab436b77428", + "sha256:b5ef909a37e9738d146519657a1aab4584018746a18f71c692f2f22168ece40c", + "sha256:b79f5ced71efd70414a9a80bbbfaa7160da307723166f09b69773153bf17c590", + "sha256:b91cceb5add79ee563bd1f70b30896bd63bc5f78a11c1f00a1e931729ca4f1f4", + "sha256:b92f5654157de1379c509b15acec9d12ecf6e3bc1996571b6cb82a4302060447", + "sha256:c04ca91dda8a61584165825907f5c967ca09e9c65fe8966ee753a3f2b019fe1e", + "sha256:c1f8afa346ccd59e4e5630d5abb67aba6a9812fddf764fd7eb11f382a345f8cc", + "sha256:c5334a71f7dc1160382d45997e29f2637c02f8a26af41073189d79b95d3321f1", + "sha256:c617d7453a80e29d9973b926983b1e700a9377dbe021faa36041c78537d7b08c", + "sha256:c632419c3870507ca20a37c8f8f5352317aca097639e524ad129f58c125c61c6", + "sha256:c6760211eee3a76316cf328f5a8bd695b47b1626d21c8a27fb3b2473a884d597", + "sha256:c698d123ce5d8f2d0cd17f73336615f6a2e3bdcedac07a1291bb4d8e7d82a05a", + "sha256:c76b32eb2ab650a29e423525e84eb197c45504b1c1e6e17b6cc91fcfeb1a4b1d", + "sha256:c8f7e90b948dc9dcfff8003f1ea3af08b29c062f681c05fd798e36daa3f7e3e8", + "sha256:c9e799dac1ffbe7b10c1fd42fe4cd51371a549c6e108249bde9cd1200e8f59b4", + "sha256:cafa48f2133d4daa028473ede7d81cd1b9f9e6925e9e4003ebdf77010ee02f35", + "sha256:ce473a2351c018b06dd8d30d5da8ab5a0831056cc53b2006e2a8028172c37ce5", + "sha256:d31ed4987d72aabdf521eddfb6a72988703c091cfc0064330b9e5f8d6a042ff5", + "sha256:d550d7e9e7d8676b183b37d65b5cd8de13676a738973d330b59dc8312df9c5dc", + "sha256:d6adb81564af0cd428910f83fa7da46ce9ad47c56c0b22b50872bc4515d91966", + "sha256:d6f6512a90bd5cd9030a6237f5346f046c6f0e40af98657568fa45695d4de59d", + "sha256:d7031d493c4465dbc8d40bd6cafefef4bd472b17db0ab94c53e7909ee781b9ef", + "sha256:d9f75a06ecc68f159d5d7603b734e1ff6daa9497a929150f794013aa9f6e3f12", + "sha256:db7707dde9143a67b8812c7e66aeb2d843fe33cc8e374170f4d2c50bd8f2472d", + "sha256:e0397dd0b3955c61ef9b22838144aa4bef6f0796ba5cc8edfc64d468b93798b4", + "sha256:e0df046f2266e8586cf09d00588302a32923eb6386ced0ca5c9deade6af9a149", + "sha256:e14f86b871ea74c3fddc9a40e947d6a5d09def5adc2076ee61fb910a9014fb35", + "sha256:e5963ea87f88bddf7edd59644a35a0feecf75f8985430124c253612d4f7d27ae", + "sha256:e768267cbe051dd8d1c5305ba690bb153204a09bf2e3de3ae530de955f5b5580", + "sha256:e9cb79ecedfc156c0692257ac7ed415243b6c35dd969baa461a6888fc79f2f07", + "sha256:ed6f011bedca8585787e5082cce081bac3d30f54520097b2411351b3574e1219", + "sha256:f3429fb8e15b20961efca8c8b21432623d85db2228cc73fe22756c6637aa39e7", + "sha256:f35eff113ad430b5272bbfc18ba111c66ff525828f24898b4e146eb479a2cdda", + "sha256:f3a6cb95074777f1ecda2ca4fa7717caa9ee6e534f42b7575a8f0d4cb0c24013", + "sha256:f7356a6da0562190558c4fcc14f0281db191cdf4cb96e7604c06acfcee96df15", + "sha256:f88626e3f5e57432e6191cd0c5d6d6b319b635e70b40be2ffba713053e5147dd", + "sha256:fad784a31869747df4ac968a351e070c06ca377549e4ace94775aaa3ab33ee06", + "sha256:fc869af5cba24d45fb0399b0cfdbcefcf6910bf4dee5d74036a57cf5264b3ff4", + "sha256:fee513135b5a58f3bb6d89e48326cd5aa308e4bcdf2f7d59f67c861ada482bf8" ], "markers": "python_version >= '3.9'", - "version": "==0.22.3" + "version": "==0.23.1" }, "six": { "hashes": [ @@ -1594,7 +1614,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" }, "werkzeug": { @@ -1990,12 +2010,12 @@ }, "pytest": { "hashes": [ - "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", - "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.4" + "version": "==8.3.5" }, "requests": { "hashes": [ @@ -2019,7 +2039,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" } } diff --git a/dbrepo-search-service/init/Pipfile.lock b/dbrepo-search-service/init/Pipfile.lock index 11510c1f53745a2c4bd2e01476fdef323f4423b8..9b7988600bb3c2454fea97c28357607adefc8b45 100644 --- a/dbrepo-search-service/init/Pipfile.lock +++ b/dbrepo-search-service/init/Pipfile.lock @@ -26,90 +26,90 @@ }, "aiohttp": { "hashes": [ - "sha256:0450ada317a65383b7cce9576096150fdb97396dcfe559109b403c7242faffef", - "sha256:0b5263dcede17b6b0c41ef0c3ccce847d82a7da98709e75cf7efde3e9e3b5cae", - "sha256:0d5176f310a7fe6f65608213cc74f4228e4f4ce9fd10bcb2bb6da8fc66991462", - "sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a", - "sha256:145a73850926018ec1681e734cedcf2716d6a8697d90da11284043b745c286d5", - "sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0", - "sha256:246067ba0cf5560cf42e775069c5d80a8989d14a7ded21af529a4e10e3e0f0e6", - "sha256:2c311e2f63e42c1bf86361d11e2c4a59f25d9e7aabdbdf53dc38b885c5435cdb", - "sha256:2cee3b117a8d13ab98b38d5b6bdcd040cfb4181068d05ce0c474ec9db5f3c5bb", - "sha256:2de1378f72def7dfb5dbd73d86c19eda0ea7b0a6873910cc37d57e80f10d64e1", - "sha256:30f546358dfa0953db92ba620101fefc81574f87b2346556b90b5f3ef16e55ce", - "sha256:34245498eeb9ae54c687a07ad7f160053911b5745e186afe2d0c0f2898a1ab8a", - "sha256:392432a2dde22b86f70dd4a0e9671a349446c93965f261dbaecfaf28813e5c42", - "sha256:3c0600bcc1adfaaac321422d615939ef300df81e165f6522ad096b73439c0f58", - "sha256:4016e383f91f2814e48ed61e6bda7d24c4d7f2402c75dd28f7e1027ae44ea204", - "sha256:40cd36749a1035c34ba8d8aaf221b91ca3d111532e5ccb5fa8c3703ab1b967ed", - "sha256:413ad794dccb19453e2b97c2375f2ca3cdf34dc50d18cc2693bd5aed7d16f4b9", - "sha256:4a93d28ed4b4b39e6f46fd240896c29b686b75e39cc6992692e3922ff6982b4c", - "sha256:4ee84c2a22a809c4f868153b178fe59e71423e1f3d6a8cd416134bb231fbf6d3", - "sha256:50c5c7b8aa5443304c55c262c5693b108c35a3b61ef961f1e782dd52a2f559c7", - "sha256:525410e0790aab036492eeea913858989c4cb070ff373ec3bc322d700bdf47c1", - "sha256:526c900397f3bbc2db9cb360ce9c35134c908961cdd0ac25b1ae6ffcaa2507ff", - "sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802", - "sha256:584096938a001378484aa4ee54e05dc79c7b9dd933e271c744a97b3b6f644957", - "sha256:6130459189e61baac5a88c10019b21e1f0c6d00ebc770e9ce269475650ff7f73", - "sha256:67453e603cea8e85ed566b2700efa1f6916aefbc0c9fcb2e86aaffc08ec38e78", - "sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef", - "sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e", - "sha256:74bd573dde27e58c760d9ca8615c41a57e719bff315c9adb6f2a4281a28e8798", - "sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0", - "sha256:76719dd521c20a58a6c256d058547b3a9595d1d885b830013366e27011ffe804", - "sha256:7c3623053b85b4296cd3925eeb725e386644fd5bc67250b3bb08b0f144803e7b", - "sha256:7e44eba534381dd2687be50cbd5f2daded21575242ecfdaf86bbeecbc38dae8e", - "sha256:7fe3d65279bfbee8de0fb4f8c17fc4e893eed2dba21b2f680e930cc2b09075c5", - "sha256:8340def6737118f5429a5df4e88f440746b791f8f1c4ce4ad8a595f42c980bd5", - "sha256:84ede78acde96ca57f6cf8ccb8a13fbaf569f6011b9a52f870c662d4dc8cd854", - "sha256:850ff6155371fd802a280f8d369d4e15d69434651b844bde566ce97ee2277420", - "sha256:87a2e00bf17da098d90d4145375f1d985a81605267e7f9377ff94e55c5d769eb", - "sha256:88d385b8e7f3a870146bf5ea31786ef7463e99eb59e31db56e2315535d811f55", - "sha256:8a2fb742ef378284a50766e985804bd6adb5adb5aa781100b09befdbfa757b65", - "sha256:8dc0fba9a74b471c45ca1a3cb6e6913ebfae416678d90529d188886278e7f3f6", - "sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1", - "sha256:8fd12d0f989c6099e7b0f30dc6e0d1e05499f3337461f0b2b0dadea6c64b89df", - "sha256:9060addfa4ff753b09392efe41e6af06ea5dd257829199747b9f15bfad819460", - "sha256:930ffa1925393381e1e0a9b82137fa7b34c92a019b521cf9f41263976666a0d6", - "sha256:936d8a4f0f7081327014742cd51d320296b56aa6d324461a13724ab05f4b2933", - "sha256:97fe431f2ed646a3b56142fc81d238abcbaff08548d6912acb0b19a0cadc146b", - "sha256:9bd8695be2c80b665ae3f05cb584093a1e59c35ecb7d794d1edd96e8cc9201d7", - "sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259", - "sha256:a478aa11b328983c4444dacb947d4513cb371cd323f3845e53caeda6be5589d5", - "sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0", - "sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9", - "sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9", - "sha256:a7442662afebbf7b4c6d28cb7aab9e9ce3a5df055fc4116cc7228192ad6cb484", - "sha256:aa8a8caca81c0a3e765f19c6953416c58e2f4cc1b84829af01dd1c771bb2f91f", - "sha256:ab3247d58b393bda5b1c8f31c9edece7162fc13265334217785518dd770792b8", - "sha256:b10a47e5390c4b30a0d58ee12581003be52eedd506862ab7f97da7a66805befb", - "sha256:b34508f1cd928ce915ed09682d11307ba4b37d0708d1f28e5774c07a7674cac9", - "sha256:b8d3bb96c147b39c02d3db086899679f31958c5d81c494ef0fc9ef5bb1359b3d", - "sha256:b9d45dbb3aaec05cf01525ee1a7ac72de46a8c425cb75c003acd29f76b1ffe94", - "sha256:bf4480a5438f80e0f1539e15a7eb8b5f97a26fe087e9828e2c0ec2be119a9f72", - "sha256:c160a04283c8c6f55b5bf6d4cad59bb9c5b9c9cd08903841b25f1f7109ef1259", - "sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f", - "sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9", - "sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df", - "sha256:ce1bb21fc7d753b5f8a5d5a4bae99566386b15e716ebdb410154c16c91494d7f", - "sha256:d1c031a7572f62f66f1257db37ddab4cb98bfaf9b9434a3b4840bf3560f5e788", - "sha256:d589264dbba3b16e8951b6f145d1e6b883094075283dafcab4cdd564a9e353a0", - "sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c", - "sha256:e10c440d142fa8b32cfdb194caf60ceeceb3e49807072e0dc3a8887ea80e8c16", - "sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d", - "sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250", - "sha256:e4cecdb52aaa9994fbed6b81d4568427b6002f0a91c322697a4bfcc2b2363f5a", - "sha256:e5148ca8955affdfeb864aca158ecae11030e952b25b3ae15d4e2b5ba299bad2", - "sha256:e6b2732ef3bafc759f653a98881b5b9cdef0716d98f013d376ee8dfd7285abf1", - "sha256:ea756b5a7bac046d202a9a3889b9a92219f885481d78cd318db85b15cc0b7bcf", - "sha256:edb69b9589324bdc40961cdf0657815df674f1743a8d5ad9ab56a99e4833cfdd", - "sha256:f0203433121484b32646a5f5ea93ae86f3d9559d7243f07e8c0eab5ff8e3f70e", - "sha256:f6a19bcab7fbd8f8649d6595624856635159a6527861b9cdc3447af288a00c00", - "sha256:f752e80606b132140883bb262a457c475d219d7163d996dc9072434ffb0784c4", - "sha256:f7914ab70d2ee8ab91c13e5402122edbc77821c66d2758abb53aabe87f013287" + "sha256:00c8ac69e259c60976aa2edae3f13d9991cf079aaa4d3cd5a49168ae3748dee3", + "sha256:01816f07c9cc9d80f858615b1365f8319d6a5fd079cd668cc58e15aafbc76a54", + "sha256:02876bf2f69b062584965507b07bc06903c2dc93c57a554b64e012d636952654", + "sha256:0e9eb7e5764abcb49f0e2bd8f5731849b8728efbf26d0cac8e81384c95acec3f", + "sha256:0f6b2c5b4a4d22b8fb2c92ac98e0747f5f195e8e9448bfb7404cd77e7bfa243f", + "sha256:1982c98ac62c132d2b773d50e2fcc941eb0b8bad3ec078ce7e7877c4d5a2dce7", + "sha256:1e83fb1991e9d8982b3b36aea1e7ad27ea0ce18c14d054c7a404d68b0319eebb", + "sha256:25de43bb3cf83ad83efc8295af7310219af6dbe4c543c2e74988d8e9c8a2a917", + "sha256:28a772757c9067e2aee8a6b2b425d0efaa628c264d6416d283694c3d86da7689", + "sha256:2a4a13dfbb23977a51853b419141cd0a9b9573ab8d3a1455c6e63561387b52ff", + "sha256:2a8a6bc19818ac3e5596310ace5aa50d918e1ebdcc204dc96e2f4d505d51740c", + "sha256:2eabb269dc3852537d57589b36d7f7362e57d1ece308842ef44d9830d2dc3c90", + "sha256:35cda4e07f5e058a723436c4d2b7ba2124ab4e0aa49e6325aed5896507a8a42e", + "sha256:42d689a5c0a0c357018993e471893e939f555e302313d5c61dfc566c2cad6185", + "sha256:4586a68730bd2f2b04a83e83f79d271d8ed13763f64b75920f18a3a677b9a7f0", + "sha256:47dc018b1b220c48089b5b9382fbab94db35bef2fa192995be22cbad3c5730c8", + "sha256:507ab05d90586dacb4f26a001c3abf912eb719d05635cbfad930bdbeb469b36c", + "sha256:5194143927e494616e335d074e77a5dac7cd353a04755330c9adc984ac5a628e", + "sha256:51c3ff9c7a25f3cad5c09d9aacbc5aefb9267167c4652c1eb737989b554fe278", + "sha256:55789e93c5ed71832e7fac868167276beadf9877b85697020c46e9a75471f55f", + "sha256:5724cc77f4e648362ebbb49bdecb9e2b86d9b172c68a295263fa072e679ee69d", + "sha256:5ad8f1c19fe277eeb8bc45741c6d60ddd11d705c12a4d8ee17546acff98e0802", + "sha256:5ceb81a4db2decdfa087381b5fc5847aa448244f973e5da232610304e199e7b2", + "sha256:64815c6f02e8506b10113ddbc6b196f58dbef135751cc7c32136df27b736db09", + "sha256:66047eacbc73e6fe2462b77ce39fc170ab51235caf331e735eae91c95e6a11e4", + "sha256:669dd33f028e54fe4c96576f406ebb242ba534dd3a981ce009961bf49960f117", + "sha256:684eea71ab6e8ade86b9021bb62af4bf0881f6be4e926b6b5455de74e420783a", + "sha256:6b35aab22419ba45f8fc290d0010898de7a6ad131e468ffa3922b1b0b24e9d2e", + "sha256:7104d5b3943c6351d1ad7027d90bdd0ea002903e9f610735ac99df3b81f102ee", + "sha256:718d5deb678bc4b9d575bfe83a59270861417da071ab44542d0fcb6faa686636", + "sha256:747ec46290107a490d21fe1ff4183bef8022b848cf9516970cb31de6d9460088", + "sha256:7836587eef675a17d835ec3d98a8c9acdbeb2c1d72b0556f0edf4e855a25e9c1", + "sha256:78e4dd9c34ec7b8b121854eb5342bac8b02aa03075ae8618b6210a06bbb8a115", + "sha256:7b77ee42addbb1c36d35aca55e8cc6d0958f8419e458bb70888d8c69a4ca833d", + "sha256:7c1b20a1ace54af7db1f95af85da530fe97407d9063b7aaf9ce6a32f44730778", + "sha256:7f27eec42f6c3c1df09cfc1f6786308f8b525b8efaaf6d6bd76c1f52c6511f6a", + "sha256:82c249f2bfa5ecbe4a1a7902c81c0fba52ed9ebd0176ab3047395d02ad96cfcb", + "sha256:85fa0b18558eb1427090912bd456a01f71edab0872f4e0f9e4285571941e4090", + "sha256:89ce611b1eac93ce2ade68f1470889e0173d606de20c85a012bfa24be96cf867", + "sha256:8ce789231404ca8fff7f693cdce398abf6d90fd5dae2b1847477196c243b1fbb", + "sha256:90d571c98d19a8b6e793b34aa4df4cee1e8fe2862d65cc49185a3a3d0a1a3996", + "sha256:9229d8613bd8401182868fe95688f7581673e1c18ff78855671a4b8284f47bcb", + "sha256:93a1f7d857c4fcf7cabb1178058182c789b30d85de379e04f64c15b7e88d66fb", + "sha256:967b93f21b426f23ca37329230d5bd122f25516ae2f24a9cea95a30023ff8283", + "sha256:9840be675de208d1f68f84d578eaa4d1a36eee70b16ae31ab933520c49ba1325", + "sha256:9862d077b9ffa015dbe3ce6c081bdf35135948cb89116e26667dd183550833d1", + "sha256:9b5b37c863ad5b0892cc7a4ceb1e435e5e6acd3f2f8d3e11fa56f08d3c67b820", + "sha256:9e64ca2dbea28807f8484c13f684a2f761e69ba2640ec49dacd342763cc265ef", + "sha256:9fe4eb0e7f50cdb99b26250d9328faef30b1175a5dbcfd6d0578d18456bac567", + "sha256:a01fe9f1e05025eacdd97590895e2737b9f851d0eb2e017ae9574d9a4f0b6252", + "sha256:a08ad95fcbd595803e0c4280671d808eb170a64ca3f2980dd38e7a72ed8d1fea", + "sha256:a4fe27dbbeec445e6e1291e61d61eb212ee9fed6e47998b27de71d70d3e8777d", + "sha256:a7d474c5c1f0b9405c1565fafdc4429fa7d986ccbec7ce55bc6a330f36409cad", + "sha256:a86dc177eb4c286c19d1823ac296299f59ed8106c9536d2b559f65836e0fb2c6", + "sha256:aa36c35e94ecdb478246dd60db12aba57cfcd0abcad43c927a8876f25734d496", + "sha256:ab915a57c65f7a29353c8014ac4be685c8e4a19e792a79fe133a8e101111438e", + "sha256:af55314407714fe77a68a9ccaab90fdb5deb57342585fd4a3a8102b6d4370080", + "sha256:afcb6b275c2d2ba5d8418bf30a9654fa978b4f819c2e8db6311b3525c86fe637", + "sha256:b27961d65639128336b7a7c3f0046dcc62a9443d5ef962e3c84170ac620cec47", + "sha256:b5b95787335c483cd5f29577f42bbe027a412c5431f2f80a749c80d040f7ca9f", + "sha256:b73a2b139782a07658fbf170fe4bcdf70fc597fae5ffe75e5b67674c27434a9f", + "sha256:b88aca5adbf4625e11118df45acac29616b425833c3be7a05ef63a6a4017bfdb", + "sha256:b992778d95b60a21c4d8d4a5f15aaab2bd3c3e16466a72d7f9bfd86e8cea0d4b", + "sha256:ba40b7ae0f81c7029583a338853f6607b6d83a341a3dcde8bed1ea58a3af1df9", + "sha256:baae005092e3f200de02699314ac8933ec20abf998ec0be39448f6605bce93df", + "sha256:c4bea08a6aad9195ac9b1be6b0c7e8a702a9cec57ce6b713698b4a5afa9c2e33", + "sha256:c6070bcf2173a7146bb9e4735b3c62b2accba459a6eae44deea0eb23e0035a23", + "sha256:c929f9a7249a11e4aa5c157091cfad7f49cc6b13f4eecf9b747104befd9f56f2", + "sha256:c97be90d70f7db3aa041d720bfb95f4869d6063fcdf2bb8333764d97e319b7d0", + "sha256:ce10ddfbe26ed5856d6902162f71b8fe08545380570a885b4ab56aecfdcb07f4", + "sha256:cf1f31f83d16ec344136359001c5e871915c6ab685a3d8dee38e2961b4c81730", + "sha256:d2b25b2eeb35707113b2d570cadc7c612a57f1c5d3e7bb2b13870fe284e08fc0", + "sha256:d33851d85537bbf0f6291ddc97926a754c8f041af759e0aa0230fe939168852b", + "sha256:e06cf4852ce8c4442a59bae5a3ea01162b8fcb49ab438d8548b8dc79375dad8a", + "sha256:e271beb2b1dabec5cd84eb488bdabf9758d22ad13471e9c356be07ad139b3012", + "sha256:f55d0f242c2d1fcdf802c8fabcff25a9d85550a4cf3a9cf5f2a6b5742c992839", + "sha256:f81cba651db8795f688c589dd11a4fbb834f2e59bbf9bb50908be36e416dc760", + "sha256:fa1fb1b61881c8405829c50e9cc5c875bfdbf685edf57a76817dfb50643e4a1a", + "sha256:fa48dac27f41b36735c807d1ab093a8386701bbf00eb6b89a0f69d9fa26b3671", + "sha256:fbfef0666ae9e07abfa2c54c212ac18a1f63e13e0760a769f70b5717742f3ece", + "sha256:fe7065e2215e4bba63dc00db9ae654c1ba3950a5fff691475a32f511142fcddb" ], "markers": "python_version >= '3.9'", - "version": "==3.11.12" + "version": "==3.11.13" }, "aiosignal": { "hashes": [ @@ -259,7 +259,7 @@ }, "dbrepo": { "hashes": [ - "sha256:779e7ee84ae91131e16100fee7143013b4c231dcd3990d418d024ff76af271e9" + "sha256:7ba35243c4ead72be2bf2a2d00a3fbbae4a9c7dabb872cca8ed1b1ce77720b5d" ], "path": "./lib/dbrepo-1.7.0.tar.gz" }, @@ -639,7 +639,7 @@ "sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610", "sha256:f6b3dfc7661f8842babd8ea07e9897fe3d9b69a1d7e5fbb743e4160f9387833b" ], - "markers": "python_version == '3.11'", + "markers": "python_version >= '3.10'", "version": "==2.2.3" }, "opensearch-py": { @@ -725,91 +725,107 @@ }, "propcache": { "hashes": [ - "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", - "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", - "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", - "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", - "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", - "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", - "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", - "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", - "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", - "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", - "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", - "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", - "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", - "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", - "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", - "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", - "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae", - "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", - "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", - "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", - "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", - "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", - "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", - "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", - "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", - "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", - "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", - "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", - "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587", - "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097", - "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", - "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", - "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", - "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541", - "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", - "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", - "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", - "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d", - "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", - "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", - "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", - "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf", - "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1", - "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04", - "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", - "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", - "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb", - "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b", - "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", - "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", - "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", - "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4", - "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", - "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e", - "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", - "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", - "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", - "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", - "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", - "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", - "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", - "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", - "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", - "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681", - "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347", - "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", - "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", - "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", - "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", - "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", - "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", - "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", - "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", - "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", - "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", - "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", - "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", - "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16", - "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", - "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", - "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd", - "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212" + "sha256:02df07041e0820cacc8f739510078f2aadcfd3fc57eaeeb16d5ded85c872c89e", + "sha256:03acd9ff19021bd0567582ac88f821b66883e158274183b9e5586f678984f8fe", + "sha256:03c091bb752349402f23ee43bb2bff6bd80ccab7c9df6b88ad4322258d6960fc", + "sha256:07700939b2cbd67bfb3b76a12e1412405d71019df00ca5697ce75e5ef789d829", + "sha256:0c3e893c4464ebd751b44ae76c12c5f5c1e4f6cbd6fbf67e3783cd93ad221863", + "sha256:119e244ab40f70a98c91906d4c1f4c5f2e68bd0b14e7ab0a06922038fae8a20f", + "sha256:11ae6a8a01b8a4dc79093b5d3ca2c8a4436f5ee251a9840d7790dccbd96cb649", + "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6", + "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c", + "sha256:1c8f7d896a16da9455f882870a507567d4f58c53504dc2d4b1e1d386dfe4588a", + "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c", + "sha256:24c04f8fbf60094c531667b8207acbae54146661657a1b1be6d3ca7773b7a545", + "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e", + "sha256:26a67e5c04e3119594d8cfae517f4b9330c395df07ea65eab16f3d559b7068fe", + "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075", + "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57", + "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf", + "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d", + "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc", + "sha256:3b812b3cb6caacd072276ac0492d249f210006c57726b6484a1e1805b3cfeea0", + "sha256:3c6ec957025bf32b15cbc6b67afe233c65b30005e4c55fe5768e4bb518d712f1", + "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64", + "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340", + "sha256:4544699674faf66fb6b4473a1518ae4999c1b614f0b8297b1cef96bac25381db", + "sha256:46ed02532cb66612d42ae5c3929b5e98ae330ea0f3900bc66ec5f4862069519b", + "sha256:49ea05212a529c2caffe411e25a59308b07d6e10bf2505d77da72891f9a05641", + "sha256:4fa0e7c9c3cf7c276d4f6ab9af8adddc127d04e0fcabede315904d2ff76db626", + "sha256:507c5357a8d8b4593b97fb669c50598f4e6cccbbf77e22fa9598aba78292b4d7", + "sha256:549722908de62aa0b47a78b90531c022fa6e139f9166be634f667ff45632cc92", + "sha256:58e6d2a5a7cb3e5f166fd58e71e9a4ff504be9dc61b88167e75f835da5764d07", + "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e", + "sha256:5d62c4f6706bff5d8a52fd51fec6069bef69e7202ed481486c0bc3874912c787", + "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a", + "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810", + "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d", + "sha256:65a37714b8ad9aba5780325228598a5b16c47ba0f8aeb3dc0514701e4413d7c0", + "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b", + "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043", + "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3", + "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7", + "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d", + "sha256:6c929916cbdb540d3407c66f19f73387f43e7c12fa318a66f64ac99da601bcdf", + "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138", + "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c", + "sha256:742840d1d0438eb7ea4280f3347598f507a199a35a08294afdcc560c3739989d", + "sha256:75e872573220d1ee2305b35c9813626e620768248425f58798413e9c39741f46", + "sha256:794c3dd744fad478b6232289c866c25406ecdfc47e294618bdf1697e69bd64a6", + "sha256:7c0fdbdf6983526e269e5a8d53b7ae3622dd6998468821d660d0daf72779aefa", + "sha256:7c5f5290799a3f6539cc5e6f474c3e5c5fbeba74a5e1e5be75587746a940d51e", + "sha256:7c6e7e4f9167fddc438cd653d826f2222222564daed4116a02a184b464d3ef05", + "sha256:7cedd25e5f678f7738da38037435b340694ab34d424938041aa630d8bac42663", + "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f", + "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c", + "sha256:8526b0941ec5a40220fc4dfde76aed58808e2b309c03e9fa8e2260083ef7157f", + "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7", + "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f", + "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7", + "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9", + "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667", + "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86", + "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51", + "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0", + "sha256:9ff4e9ecb6e4b363430edf2c6e50173a63e0820e549918adef70515f87ced19a", + "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c", + "sha256:a2b9bf8c79b660d0ca1ad95e587818c30ccdb11f787657458d6f26a1ea18c568", + "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af", + "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25", + "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5", + "sha256:a94ffc66738da99232ddffcf7910e0f69e2bbe3a0802e54426dbf0714e1c2ffe", + "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf", + "sha256:b0c1a133d42c6fc1f5fbcf5c91331657a1ff822e87989bf4a6e2e39b818d0ee9", + "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf", + "sha256:bb2f144c6d98bb5cbc94adeb0447cfd4c0f991341baa68eee3f3b0c9c0e83767", + "sha256:be90c94570840939fecedf99fa72839aed70b0ced449b415c85e01ae67422c90", + "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c", + "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d", + "sha256:bf4298f366ca7e1ad1d21bbb58300a6985015909964077afd37559084590c929", + "sha256:c441c841e82c5ba7a85ad25986014be8d7849c3cfbdb6004541873505929a74e", + "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32", + "sha256:cd54895e4ae7d32f1e3dd91261df46ee7483a735017dc6f987904f194aa5fd14", + "sha256:d1323cd04d6e92150bcc79d0174ce347ed4b349d748b9358fd2e497b121e03c8", + "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b", + "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc", + "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa", + "sha256:df03cd88f95b1b99052b52b1bb92173229d7a674df0ab06d2b25765ee8404bce", + "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b", + "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e", + "sha256:e560fd75aaf3e5693b91bcaddd8b314f4d57e99aef8a6c6dc692f935cc1e6bbf", + "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9", + "sha256:ecc2920630283e0783c22e2ac94427f8cca29a04cfdf331467d4f661f4072dac", + "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f", + "sha256:ee0bd3a7b2e184e88d25c9baa6a9dc609ba25b76daae942edfb14499ac7ec374", + "sha256:ee25f1ac091def37c4b59d192bbe3a206298feeb89132a470325bf76ad122a1e", + "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d", + "sha256:f47d52fd9b2ac418c4890aad2f6d21a6b96183c98021f0a48497a904199f006e", + "sha256:f857034dc68d5ceb30fb60afb6ff2103087aea10a01b613985610e007053a121", + "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5", + "sha256:fddb8870bdb83456a489ab67c6b3040a8d5a55069aa6f72f9d872235fbc52f54" ], "markers": "python_version >= '3.9'", - "version": "==0.2.1" + "version": "==0.3.0" }, "pydantic": { "hashes": [ @@ -935,12 +951,12 @@ }, "pytest": { "hashes": [ - "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", - "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.4" + "version": "==8.3.5" }, "python-dateutil": { "hashes": [ @@ -1043,7 +1059,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" }, "werkzeug": { @@ -1307,7 +1323,7 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "charset-normalizer": { @@ -1480,40 +1496,44 @@ }, "cryptography": { "hashes": [ - "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7", - "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3", - "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183", - "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69", - "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a", - "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62", - "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911", - "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7", - "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a", - "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41", - "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83", - "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12", - "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864", - "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf", - "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c", - "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2", - "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b", - "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0", - "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4", - "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9", - "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008", - "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862", - "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009", - "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7", - "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f", - "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026", - "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f", - "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd", - "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420", - "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14", - "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00" + "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", + "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41", + "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", + "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5", + "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", + "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d", + "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", + "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", + "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", + "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", + "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", + "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", + "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", + "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", + "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", + "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", + "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562", + "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", + "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", + "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", + "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", + "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", + "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", + "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa", + "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb", + "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", + "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", + "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", + "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", + "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", + "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", + "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", + "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", + "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", + "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" ], "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", - "version": "==44.0.1" + "version": "==44.0.2" }, "idna": { "hashes": [ @@ -1565,12 +1585,12 @@ }, "pytest": { "hashes": [ - "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", - "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.4" + "version": "==8.3.5" }, "requests": { "hashes": [ @@ -1594,7 +1614,7 @@ "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.10'", + "markers": "python_version >= '3.9'", "version": "==2.3.0" } } diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.0-py3-none-any.whl b/dbrepo-search-service/init/lib/dbrepo-1.7.0-py3-none-any.whl index f75ec9ba7a7a4ad6c2897e38abdae20c815f56c7..385c9e224a31ae8811c03908303ea42fc2374d0a 100644 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.0-py3-none-any.whl and b/dbrepo-search-service/init/lib/dbrepo-1.7.0-py3-none-any.whl differ diff --git a/dbrepo-search-service/init/lib/dbrepo-1.7.0.tar.gz b/dbrepo-search-service/init/lib/dbrepo-1.7.0.tar.gz index be1dcfe68165001dbeacd670709955723a01e323..823a773ca48627ae548e2e0448bef1f5a224b3d8 100644 Binary files a/dbrepo-search-service/init/lib/dbrepo-1.7.0.tar.gz and b/dbrepo-search-service/init/lib/dbrepo-1.7.0.tar.gz differ diff --git a/dbrepo-search-service/init/tests/test_opensearch_client.py b/dbrepo-search-service/init/tests/test_opensearch_client.py index fe65fd060a363d5ecebf98fa006db78b6f30c555..54ef2340ab0cf7763122cbf300deb5f8d44d6fa1 100644 --- a/dbrepo-search-service/init/tests/test_opensearch_client.py +++ b/dbrepo-search-service/init/tests/test_opensearch_client.py @@ -22,7 +22,7 @@ req = Database(id="209acf92-5c9b-4633-ad99-113c86f6e948", image=ImageBrief(id="f97791b4-baf4-4b18-8f7d-3084818e6549", name="mariadb", version="11.1.3", - jdbc_method="mariadb")), + default=True)), tables=[Table(id="f94a6164-cad4-4873-a9fd-3fe5313b2e95", database_id="209acf92-5c9b-4633-ad99-113c86f6e948", name="Data", @@ -163,7 +163,7 @@ class OpenSearchClientTest(unittest.TestCase): # test try: - OpenSearchClient().delete_database(database_id=9999) + OpenSearchClient().delete_database(database_id="deadbeef-a5aa-49bb-87e7-6c6271731a1a") except opensearchpy.exceptions.NotFoundError: pass diff --git a/dbrepo-search-service/lib/dbrepo-1.7.0-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.7.0-py3-none-any.whl index f75ec9ba7a7a4ad6c2897e38abdae20c815f56c7..385c9e224a31ae8811c03908303ea42fc2374d0a 100644 Binary files a/dbrepo-search-service/lib/dbrepo-1.7.0-py3-none-any.whl and b/dbrepo-search-service/lib/dbrepo-1.7.0-py3-none-any.whl differ diff --git a/dbrepo-search-service/lib/dbrepo-1.7.0.tar.gz b/dbrepo-search-service/lib/dbrepo-1.7.0.tar.gz index be1dcfe68165001dbeacd670709955723a01e323..823a773ca48627ae548e2e0448bef1f5a224b3d8 100644 Binary files a/dbrepo-search-service/lib/dbrepo-1.7.0.tar.gz and b/dbrepo-search-service/lib/dbrepo-1.7.0.tar.gz differ diff --git a/dbrepo-search-service/tests/test_app.py b/dbrepo-search-service/tests/test_app.py index f05171299ef5fe202ee71ce5b5b347364a4eeed8..d2c8f2bd6049220b83a867562f0459b58b8f344d 100644 --- a/dbrepo-search-service/tests/test_app.py +++ b/dbrepo-search-service/tests/test_app.py @@ -22,7 +22,7 @@ req = Database(id="209acf92-5c9b-4633-ad99-113c86f6e948", image=ImageBrief(id="f97791b4-baf4-4b18-8f7d-3084818e6549", name="mariadb", version="11.1.3", - jdbc_method="mariadb")), + default=True)), tables=[Table(id="f94a6164-cad4-4873-a9fd-3fe5313b2e95", database_id="209acf92-5c9b-4633-ad99-113c86f6e948", name="Data", diff --git a/dbrepo-ui/assets/globals.css b/dbrepo-ui/assets/globals.css index 52da2e48c8c2e7589ddcbce27fe67520acd74763..90dc2854d0e2f73570e127ab550571c9de20cdf9 100644 --- a/dbrepo-ui/assets/globals.css +++ b/dbrepo-ui/assets/globals.css @@ -10,4 +10,7 @@ select.native { border-style: solid; width: 100%; } +.line-break { + white-space: pre-wrap; } + /*# sourceMappingURL=globals.css.map */ diff --git a/dbrepo-ui/assets/globals.css.map b/dbrepo-ui/assets/globals.css.map index 6f271c8f99f4295e8438524dea16b6a48b253635..13ee94918abe425675c52bd70da749839a0957fb 100644 --- a/dbrepo-ui/assets/globals.css.map +++ b/dbrepo-ui/assets/globals.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAAA,CAAE;EACA,KAAK,EAAE,sBAAsB;;AAG/B;aACc;EACZ,OAAO,EAAE,KAAK;;AAGhB,aAAc;EACZ,kBAAkB,EAAE,OAAO;EAC3B,YAAY,EAAE,KAAK;EACnB,KAAK,EAAE,IAAI", +"mappings": "AAAA,CAAE;EACA,KAAK,EAAE,sBAAsB;;AAG/B;aACc;EACZ,OAAO,EAAE,KAAK;;AAGhB,aAAc;EACZ,kBAAkB,EAAE,OAAO;EAC3B,YAAY,EAAE,KAAK;EACnB,KAAK,EAAE,IAAI;;AAGb,WAAY;EACV,WAAW,EAAE,QAAQ", "sources": ["globals.scss"], "names": [], "file": "globals.css" diff --git a/dbrepo-ui/assets/globals.scss b/dbrepo-ui/assets/globals.scss index 5d4d4e06a7cdcde8e801cccd14c0eb2f07c0824d..5e0dce3a0fff1005acb8eb9094b8a8bacbc78501 100644 --- a/dbrepo-ui/assets/globals.scss +++ b/dbrepo-ui/assets/globals.scss @@ -12,3 +12,7 @@ select.native { border-style: solid; width: 100%; } + +.line-break { + white-space: pre-wrap; +} diff --git a/dbrepo-ui/components/container/ContainerCard.vue b/dbrepo-ui/components/container/ContainerCard.vue index ed1479f64d3ad8043968e03edbfcd940190e3fb6..841333c44d913fe63150de59d83d89831a6077a2 100644 --- a/dbrepo-ui/components/container/ContainerCard.vue +++ b/dbrepo-ui/components/container/ContainerCard.vue @@ -17,7 +17,7 @@ height="20" class="font-small"> <template v-slot:default> - {{ container.count }} / {{ container.quota }} + {{ container.count }} / {{ quota }} </template> </v-progress-linear> </v-card-text> @@ -39,7 +39,16 @@ export default { } }, computed: { + quota () { + if (!this.container || !this.container.quota) { + return '∞' + } + return this.container.quota + }, utilization () { + if (!this.container || !this.container.quota) { + return 0 + } return this.container.count * 100.0 / this.container.quota }, colorVariant () { diff --git a/dbrepo-ui/components/identifier/Persist.vue b/dbrepo-ui/components/identifier/Persist.vue index f228eade289009193e99be67de0043b4e7007907..004a037c4667fac81bb65d9376d94cfb6a8b80a8 100644 --- a/dbrepo-ui/components/identifier/Persist.vue +++ b/dbrepo-ui/components/identifier/Persist.vue @@ -34,7 +34,7 @@ <v-btn v-if="canPublish" class="mr-2" - :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-content-save-outline' : null" + :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-identifier' : null" color="primary" variant="flat" :loading="loadingPublish" diff --git a/dbrepo-ui/components/identifier/Summary.vue b/dbrepo-ui/components/identifier/Summary.vue index 6ef120599b515fece88870ad832ed23a508e4ebe..dcbe2f063db7ccbeb601a70a2d1bc85e3f9a5c85 100644 --- a/dbrepo-ui/components/identifier/Summary.vue +++ b/dbrepo-ui/components/identifier/Summary.vue @@ -26,7 +26,7 @@ <v-list-item :title="$t('pages.identifier.descriptions.title')" density="compact"> - <p + <div v-for="(description, i) in identifier.descriptions" :key="`d-${i}`"> <div @@ -36,7 +36,7 @@ <span> {{ description.description }} </span> - </p> + </div> </v-list-item> <v-list-item :title="$t('pages.identifier.publisher.title')" diff --git a/dbrepo-ui/components/subset/Builder.vue b/dbrepo-ui/components/subset/Builder.vue index e66f72e362a845c4aff83c67eada608a46d52023..60f9568a3ff185f76957ada52f6c4fee9711b035 100644 --- a/dbrepo-ui/components/subset/Builder.vue +++ b/dbrepo-ui/components/subset/Builder.vue @@ -19,25 +19,13 @@ :text="$t('navigation.create')" @click="execute" /> </v-toolbar> - <v-toolbar flat> - <v-tabs - v-model="tabs" - color="primary"> - <v-tab - value="0" - :text="$t('pages.subset.subpages.create.simple.text')" /> - <v-tab - value="1" - :text="$t('pages.subset.subpages.create.expert.text')" /> - </v-tabs> - </v-toolbar> <v-card rounded="0" variant="flat"> <v-card-text> <v-form ref="form" - @submit.prevent> + @submit.prevent="$refs.form.validate()"> <v-row v-if="isView" class="mt-1" @@ -122,16 +110,16 @@ item-title="internal_name" :disabled="!table || isExecuted" :items="columns" + :rules="[v => !!v || $t('validation.required')]" + required persistent-hint clearable :variant="inputVariant" :label="$t('pages.view.subpages.create.columns.label')" :hint="$t('pages.view.subpages.create.columns.hint')" - :rules="[v => !!v || $t('validation.required')]" :loading="loadingColumns" return-object - multiple - @update:model-value="buildQuery"> + multiple> <template v-slot:prepend-item> <v-list-item @@ -157,14 +145,24 @@ <v-btn v-if="clauses.length === 0" size="small" - color="secondary" + color="tertiary" variant="flat" :text="$t('pages.subset.subpages.create.filter.text')" :disabled="clausesDisabled" - @click="addFirst" /> + @click="addFirstFilter" /> + <v-btn + v-if="clauses.length === 0 && sorts.length === 0" + class="ml-2" + size="small" + color="tertiary" + variant="flat" + :text="$t('pages.subset.subpages.create.order.text')" + :disabled="clausesDisabled" + @click="addFirstSort" /> </v-col> </v-row> - <div class="mb-5"> + <div + class="mb-5"> <v-row v-if="clauses.length > 0"> <v-col @@ -184,6 +182,9 @@ item-title="internal_name" item-value="internal_name" variant="underlined" + :rules="[v => !!v || $t('validation.required')]" + required + clearable persistent-hint :label="$t('pages.subset.subpages.create.filter.column.label')" :hint="$t('pages.subset.subpages.create.filter.column.hint')" @@ -196,9 +197,12 @@ :disabled="clausesDisabled" item-title="value" item-value="value" + :rules="[v => !!v || $t('validation.required')]" + required + clearable persistent-hint - :label="operatorHint(clause.params[1])" - :hint="$t('pages.subset.subpages.create.filter.operator.label')" + :label="$t('pages.subset.subpages.create.filter.operator.label')" + :hint="operatorHint(clause.params[1])" :items="operators"> <template v-slot:append> @@ -224,6 +228,9 @@ <v-text-field v-model="clause.params[2]" :disabled="clausesDisabled" + :rules="[v => !!v || $t('validation.required')]" + required + clearable persistent-hint :label="$t('pages.subset.subpages.create.filter.value.label')" :hint="$t('pages.subset.subpages.create.filter.value.hint')" /> @@ -237,7 +244,7 @@ color="error" variant="flat" :text="$t('pages.subset.subpages.create.filter.remove.text')" - @click="remove(idx)" /> + @click="removeFilter(idx)" /> </v-col> </v-row> <v-row @@ -257,7 +264,7 @@ :disabled="!canAdd(idx) || clausesDisabled" class="mt-2 mr-1" variant="flat" - color="secondary" + color="tertiary" size="small" :text="$t('pages.subset.subpages.create.filter.and.text')" @click="addAnd" /> @@ -265,7 +272,7 @@ :disabled="!canAdd(idx) || clausesDisabled" class="mt-2" variant="flat" - color="secondary" + color="tertiary" size="small" :text="$t('pages.subset.subpages.create.filter.or.text')" @click="addOr" /> @@ -274,33 +281,70 @@ </div> </div> </div> - </v-window-item> - <v-window-item - value="1"> + <div class="mb-5"> + <v-row + v-if="sorts.length > 0"> + <v-col + lg="8" + class="text-center"> + <pre>SORT BY</pre> + </v-col> + </v-row> + <v-row + v-for="(sort, idx) in sorts" + key="idx"> + <v-col + lg="4"> + <v-select + v-model="sort.column_id" + :disabled="clausesDisabled" + item-title="internal_name" + item-value="id" + :rules="[v => !!v || $t('validation.required')]" + required + clearable + variant="underlined" + persistent-hint + :label="$t('pages.subset.subpages.create.filter.column.label')" + :hint="$t('pages.subset.subpages.create.filter.column.hint')" + :items="columns" /> + </v-col> + <v-col + lg="4"> + <v-select + v-model="sort.direction" + :disabled="clausesDisabled" + item-title="title" + item-value="value" + clearable + persistent-hint + :label="$t('pages.subset.subpages.create.order.direction.label')" + :items="sortings" /> + </v-col> + <v-col + lg="1"> + <v-btn + :disabled="clausesDisabled" + class="mt-4" + size="small" + color="error" + variant="flat" + :text="$t('pages.subset.subpages.create.order.remove.text')" + @click="removeSort(idx)" /> + </v-col> + </v-row> + </div> <v-row - v-if="hasUnsupported" - dense> - <v-col> - <v-alert - border="start" - color="warning"> - <span> - {{ $t('pages.subset.subpages.create.expert.warn') }} - </span> - <pre style="white-space:inherit;">{{ unsupported.join(', ') }}</pre> - </v-alert> - </v-col> - </v-row> - <v-row dense> - <v-col> - {{ $t('pages.subset.subpages.create.subtitle') }} - </v-col> - </v-row> - <v-row dense> - <v-col> - <Raw - class="mt-2" - @sql="updateSql" /> + v-if="(sorts.length > 0 || clauses.length > 0) && select.length > 0"> + <v-col + lg="8"> + <v-btn + size="small" + color="tertiary" + variant="flat" + :text="$t('pages.subset.subpages.create.order.text')" + :disabled="clausesDisabled" + @click="addFirstSort" /> </v-col> </v-row> </v-window-item> @@ -315,7 +359,6 @@ import Raw from '@/components/subset/Raw.vue' import Results from '@/components/subset/Results.vue' import { useCacheStore } from '@/stores/cache.js' -import { format } from 'sql-formatter' export default { components: { @@ -335,6 +378,7 @@ export default { table: null, views: [], columns: [], + sorts: [], timestamp: null, executeDifferentTimestamp: false, dataOptions: [ @@ -347,21 +391,24 @@ export default { ], tableDetails: null, resultId: null, - valid: false, errorKeyword: null, query: { - raw: null, - formatted: null + table_id: null, + columns: [], + filter: null }, view: { is_public: true, is_schema_public: true, - name: null, - query: null + name: null }, select: [], clauses: [], tabs: 0, + sortings: [ + { title: 'Ascending ↓', value: 'asc' }, + { title: 'Descening ↑', value: 'desc' }, + ], loadingQuery: false, loadingColumns: false, cacheStore: useCacheStore() @@ -398,14 +445,6 @@ export default { } return this.database.views.map(v => v.internal_name) }, - sql () { - if (!this.query.raw) { - return '' - } - return this.query.raw.replaceAll('\n', ' ') /* remove newline */ - .replaceAll(/\s+/g, ' ') /* remove whitespace */ - .trim() - }, clausesDisabled () { return this.isExecuted }, @@ -421,36 +460,46 @@ export default { isExecuted () { return this.resultId !== null }, - valid () { - if (this.isView) { - return this.valid && !this.hasUnsupported - } - return this.sql.length > 0 && !this.hasUnsupported - }, unsupported () { if (!this.$config.public.database.unsupported) { return [] } return this.$config.public.database.unsupported.split(',') }, - hasUnsupported () { - if (!this.sql) { - return false + subset () { + if (!this.table || !this.select) { + return null } - const unsupported = this.unsupported.map(k => k.toLowerCase()) - for (let i = 0; i < unsupported.length; i++) { - if (this.sql.toLowerCase().includes(unsupported[i])) { - console.warn('query contains unsupported keyword', unsupported[i]) - return true - } + return { + table_id: this.table.id, + columns: this.select.map(column => column.id), + filter: this.clauses ? this.clauses.map(clause => { + if (clause.type === 'or' || clause.type === 'and') { + return { + type: clause.type + } + } + const filtered_column = this.table.columns.filter(column => column.internal_name === clause.params[0]) + const filtered_operator = this.database.container.image.operators.filter(operator => operator.value === clause.params[1]) + if (!filtered_column || filtered_column.length === 0 || !filtered_operator || filtered_operator.length === 0) { + return null + } + const json = { + type: clause.type, + column_id: filtered_column[0].id, + operator_id: filtered_operator[0].id, + value: clause.params[2] + } + return json + }) : null, + order: this.sorts } - return this.sql.includes(';') }, canExecute () { if (this.isView) { - return this.view.name !== null && this.view.is_public !== null && this.view.query !== null + return this.view.name !== null && this.view.is_public !== null && this.subset !== null } - return this.sql !== null && this.sql !== '' && !this.sql.includes(';') + return this.subset !== null && this.subset.columns && this.subset.columns.length > 0 && this.$refs.form.isValid }, inputVariant () { const runtimeConfig = useRuntimeConfig() @@ -462,13 +511,6 @@ export default { } }, watch: { - clauses: { - deep: true, - immediate: true, - handler () { - this.buildQuery() - } - }, table () { this.select = [] if (!this.table) { @@ -538,7 +580,7 @@ export default { /* pre-check */ this.loadingQuery = true const queryService = useQueryService() - queryService.execute(this.$route.params.database_id, { statement: this.sql }, this.timestamp, 0, 1) + queryService.execute(this.$route.params.database_id, this.subset, this.timestamp, 0, 1) .then(async (subset) => { const toast = useToastInstance() toast.success(this.$t('success.subset.create')) @@ -549,6 +591,7 @@ export default { this.loadingQuery = false const toast = useToastInstance() if (typeof code !== 'string') { + toast.error(this.$t('error.query.invalid')) return } toast.error(`${this.$t(code)}: ${message}`) @@ -556,7 +599,7 @@ export default { }, createView () { this.loadingQuery = true - this.view.query = this.sql + this.view.query = this.subset const viewService = useViewService() viewService.create(this.$route.params.database_id, this.view) .then((simpleView) => { @@ -587,39 +630,32 @@ export default { toast.error(this.$t(code)) }) }, - buildQuery () { - if (!this.table) { - return - } - const queryService = useQueryService() - const { error, reason, column, raw, formatted } = queryService.build(this.table.internal_name, this.select, this.columnTypes, this.clauses) - if (error) { - const toast = useToastInstance() - toast.error(this.$t('error.query.' + reason) + ' ' + column) - return - } - this.query.raw = raw - if (this.isView) { - this.view.query = raw - } - this.query.formatted = formatted - }, canAdd (idx) { return idx === this.clauses.length - 1 }, - addFirst () { + addFirstFilter () { const column = (this.columnNames && this.columnNames.length) ? this.columnNames[0] : '' this.clauses.push({ type: 'where', params: [column, '=', ''] }) + this.$refs.form.validate() + }, + addFirstSort () { + if (this.sorts.length === 0) { + this.columns.filter(c => this.table.constraints.primary_key.map(pk => + pk.column.id).includes(c.id)).forEach(pk => this.sorts.push({ column_id: pk.id, direction: 'asc' })) + } else { + this.sorts.push({ column_id: null, direction: null}) + } + this.$refs.form.validate() }, addAnd () { this.clauses.push({ type: 'and' }) - this.addFirst() + this.addFirstFilter() }, addOr () { this.clauses.push({ type: 'or' }) - this.addFirst() + this.addFirstFilter() }, - remove (idx) { + removeFilter (idx) { if (idx === 0) { if (this.clauses.length === 1) { this.clauses.splice(idx, 1) @@ -631,23 +667,17 @@ export default { this.clauses.splice(idx - 1, 2) } }, - updateSql (event) { - const { raw } = event - if (raw) { - this.query.raw = raw - if (this.isView) { - this.view.query = raw - } - this.query.formatted = format(raw, { - language: 'mysql', - keywordCase: 'upper' - }) + removeSort (idx) { + if (idx === 0) { + this.sorts.splice(idx, 1) + } else { + // remove current and previous + this.sorts.splice(idx - 1, 1) } }, toggleColumns () { if (this.select.length !== this.columns.length) { this.select = this.columns - this.buildQuery() } else { this.select = [] } @@ -661,7 +691,7 @@ export default { }, operatorHint (value) { const filter = this.operators.filter(o => o.value === value) - if (filter.length !== 1) { + if (filter.length !== 1 || filter[0].display_name === filter[0].value) { return null } return filter[0].display_name diff --git a/dbrepo-ui/components/subset/SubsetToolbar.vue b/dbrepo-ui/components/subset/SubsetToolbar.vue index 2e6dae63025d72ad8890ad70ef69daca040cc333..070cdb4a3bb66678f81dd8b42b0d5e69ddf25ab6 100644 --- a/dbrepo-ui/components/subset/SubsetToolbar.vue +++ b/dbrepo-ui/components/subset/SubsetToolbar.vue @@ -34,7 +34,7 @@ color="primary" variant="flat" class="mr-2" - :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-content-save-outline' : null" + :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-identifier' : null" :to="`/database/${$route.params.database_id}/subset/${$route.params.subset_id}/persist`"> {{ ($vuetify.display.lgAndUp ? $t('toolbars.subset.pid.xl') + ' ' : '') + $t('toolbars.subset.pid.permanent') }} </v-btn> diff --git a/dbrepo-ui/components/table/TableToolbar.vue b/dbrepo-ui/components/table/TableToolbar.vue index e09cd67cba31e8d3aaec7e9055078fa354bd4ded..7311e0afd5775a620f6cddbd2fef005d192fc782 100644 --- a/dbrepo-ui/components/table/TableToolbar.vue +++ b/dbrepo-ui/components/table/TableToolbar.vue @@ -48,7 +48,7 @@ :to="`/database/${$route.params.database_id}/view/create?tid=${$route.params.table_id}`" /> <v-btn v-if="canGetPid" - :prepend-icon="$vuetify.display.mdAndUp ? 'mdi-content-save-outline' : null" + :prepend-icon="$vuetify.display.mdAndUp ? 'mdi-identifier' : null" color="primary" variant="flat" :text="($vuetify.display.mdAndUp ? 'Get ' : '') + 'PID'" diff --git a/dbrepo-ui/components/view/ViewToolbar.vue b/dbrepo-ui/components/view/ViewToolbar.vue index 9f44c8d4804d8b9ca8b81bdbab5e95b7ae5ce5c5..b5dc0caac551fc7017d2bdca301ac7aad6021ab8 100644 --- a/dbrepo-ui/components/view/ViewToolbar.vue +++ b/dbrepo-ui/components/view/ViewToolbar.vue @@ -19,7 +19,7 @@ <v-btn v-if="canCreatePid" class="mr-2" - :prepend-icon="$vuetify.display.mdAndUp ? 'mdi-content-save-outline' : null" + :prepend-icon="$vuetify.display.mdAndUp ? 'mdi-identifier' : null" variant="flat" color="primary" :text="($vuetify.display.mdAndUp ? $t('toolbars.view.pid.xl') + ' ' : '') + $t('toolbars.view.pid.permanent')" diff --git a/dbrepo-ui/composables/query-service.ts b/dbrepo-ui/composables/query-service.ts index c0d5c0db7c6bab8c949ec581a023a138f7c065ac..5a86c09d1b1b7017e362a62c0cc5df33c545fd6c 100644 --- a/dbrepo-ui/composables/query-service.ts +++ b/dbrepo-ui/composables/query-service.ts @@ -1,4 +1,3 @@ -import {format} from 'sql-formatter' import type {AxiosRequestConfig} from 'axios' import {axiosErrorToApiError} from '@/utils' @@ -77,11 +76,11 @@ export const useQueryService = (): any => { }) } - async function execute(databaseId: string, data: ExecuteStatementDto, timestamp: Date | null, page: number, size: number): Promise<QueryResultDto> { + async function execute(databaseId: string, subset: SubsetDto, timestamp: Date | null, page: number, size: number): Promise<QueryResultDto> { const axios = useAxiosInstance() console.debug('execute query in database with id', databaseId) return new Promise<QueryResultDto>((resolve, reject) => { - axios.post<QueryResultDto>(`/api/database/${databaseId}/subset`, data, {params: mapFilter(timestamp, page, size), timeout: 600_000}) + axios.post<QueryResultDto>(`/api/database/${databaseId}/subset`, subset, {params: mapFilter(timestamp, page, size), timeout: 600_000}) .then((response) => { console.info('Executed query with id', response.data.id, ' in database with id', databaseId) const result: QueryResultDto = { @@ -136,69 +135,6 @@ export const useQueryService = (): any => { }) } - function build(table: TableDto, columns: ColumnDto[], types: DataTypeDto[], clauses: any[]): QueryBuildResultDto { - var sql = 'SELECT' - for (let i = 0; i < columns.length; i++) { - sql += `${i > 0 ? ',' : ''} \`${columns[i].internal_name}\`` - } - sql += ` FROM \`${table}\`` - if (clauses.length > 0) { - sql += ' WHERE' - for (let i = 0; i < clauses.length; i++) { - const clause = clauses[i] - if (clause.type === 'and' || clause.type === 'or') { - sql += ` ${clause.type.toUpperCase()} ` - continue - } - const filteredColumn = columns.filter(c => c.internal_name === clause.params[0]) - if (filteredColumn.length === 0) { - return { - error: true, - reason: 'column.exists', - column: clause.params[0], - raw: null, - formatted: null - } - } - sql += ` \`${clause.params[0]}\` ${clause.params[1]} ` - const filteredType = types.filter(t => t.value === filteredColumn[0].type) - if (filteredType.length === 0) { - return { - error: true, - reason: 'exists', - column: filteredColumn[0].type, - raw: null, - formatted: null - } - } - if (!filteredType[0].is_buildable) { - return { - error: true, - reason: 'build', - column: filteredColumn[0].type, - raw: null, - formatted: null - } - } - if (filteredType[0].is_quoted) { - sql += `'${clause.params[2]}'` - } else { - sql += `${clause.params[2]}` - } - } - } - return { - error: false, - reason: null, - column: null, - raw: sql, - formatted: format(sql, { - language: 'mysql', - keywordCase: 'upper' - }) - } - } - function mapFilter(timestamp: Date | null, page: number, size: number) { if (!timestamp) { return {page, size} @@ -206,5 +142,5 @@ export const useQueryService = (): any => { return {timestamp, page, size} } - return {findAll, findOne, update, exportCsv, execute, reExecuteData, reExecuteCount, build} + return {findAll, findOne, update, exportCsv, execute, reExecuteData, reExecuteCount} } diff --git a/dbrepo-ui/dto/index.ts b/dbrepo-ui/dto/index.ts index 2f20f174299cc789abe52c94f39d121dd8faa30d..e804c3eabf60d0bd0ba4996084c76658673d16d3 100644 --- a/dbrepo-ui/dto/index.ts +++ b/dbrepo-ui/dto/index.ts @@ -437,8 +437,9 @@ interface DatabaseModifyImageDto { interface ViewCreateDto { name: string; - query: string; + query: SubsetDto; is_public: boolean; + is_schema_public: boolean; } interface ViewUpdateDto { @@ -477,10 +478,6 @@ interface TableCsvDeleteDto { keys: Map<string, string>; } -interface ExecuteStatementDto { - statement: string; -} - interface ApiErrorDto { status: string; message: string; @@ -599,6 +596,25 @@ interface ImportCsv { line_termination: string; } +interface FilterDto { + type: string; + value: string; + column_id: string; + operator_id: string; +} + +interface OrderDto { + column_id: string; + direction: string; +} + +interface SubsetDto { + table_id: string; + columns: string[]; + filter: FilterDto[] | null; + order: OrderDto[] | null; +} + interface QueryResultDto { id: string | null; result: any; diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json index a42a56411b825f5eb011b311ce995e9f291c7725..55a9692c2d4650d2fb3970322aafe026e2da8d10 100644 --- a/dbrepo-ui/locales/en-US.json +++ b/dbrepo-ui/locales/en-US.json @@ -1015,6 +1015,15 @@ "or": { "text": "Add \"OR\" Filter" } + }, + "order": { + "text": "Add Sorting", + "direction": { + "label": "Direction" + }, + "remove": { + "text": "Remove" + } } } } @@ -1270,7 +1279,8 @@ "view": { "create": "Failed to create view", "missing": "Failed to find view in metadata database", - "invalid": "Failed to map view query to columns in data service" + "invalid": "Failed to map view query to columns in data service", + "exists": "View with this name exists already" }, "broker": { "connection": "Failed to contact broker service", diff --git a/dbrepo-ui/nuxt.config.ts b/dbrepo-ui/nuxt.config.ts index b3da7bd98c657513e85c64cd51fac4c118d433b7..9d6a18146f688fe76c81921334637bb921df42fa 100644 --- a/dbrepo-ui/nuxt.config.ts +++ b/dbrepo-ui/nuxt.config.ts @@ -90,7 +90,6 @@ export default defineNuxtConfig({ prefix: '/' }, database: { - unsupported: 'AVG,BIT_AND,BIT_OR,BIT_XOR,COUNT,COUNTDISTINCT,GROUP_CONCAT,JSON_ARRAYAGG,JSON_OBJECTAGG,MAX,MIN,STD,STDDEV,STDDEV_POP,STDDEV_SAMP,SUM,VARIANCE,VAR_POP,VAR_SAMP,--', image: { width: 200, height: 200 diff --git a/dbrepo-ui/package.json b/dbrepo-ui/package.json index d7d4917e9f45f113156951746486755d91ae7bed..77edd08c86fa398d83389a474e8ed458b6913651 100644 --- a/dbrepo-ui/package.json +++ b/dbrepo-ui/package.json @@ -32,7 +32,6 @@ "parse-md": "^3.0.3", "pinia": "^2.1.7", "qs": "^6.11.2", - "sql-formatter": "^15.2.0", "tus-js-client": "^4.0.1", "vue": "^3.4.21", "vue-axios": "^3.5.2", diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue index d3b5f624d7425992e4858caa2e000dcc82c1ec59..d0140a6fa1295d0abda828a491f3765d668548a7 100644 --- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue @@ -40,17 +40,18 @@ :resource="identifier" /> </v-list-item> <v-list-item - v-if="subset.creator" + v-if="subset.owner" :title="$t('pages.subset.creator.title')" density="compact"> <UserBadge - :user="subset.creator" + :user="subset.owner" :other-user="cacheUser" /> </v-list-item> <v-list-item :title="$t('pages.subset.query.title')" density="compact"> - <pre>{{ subset.query }}</pre> + <pre + class="line-break">{{ subset.query }}</pre> </v-list-item> <v-list-item :title="`${$t('pages.subset.query.title')} ${$t('pages.subset.hash.title')}`" diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue index 395be401c08730d0b9880fbbe21c61ccf6bf2db7..b5266b79f20ac518984a716e1c130580f7dd1f56 100644 --- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue +++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/info.vue @@ -32,7 +32,8 @@ </v-list-item> <v-list-item :title="$t('pages.view.query.title')"> - <pre>{{ view.query }}</pre> + <pre + class="line-break">{{ view.query }}</pre> </v-list-item> <v-list-item :title="$t('pages.view.owner.title')"> diff --git a/helm/dbrepo/files/01-setup-schema.sql b/helm/dbrepo/files/01-setup-schema.sql index 17d303ea7d6001e73a55b19cc286e8d9980e1d35..12e0f02a169c969ea0036652dc2198b79e492ebf 100644 --- a/helm/dbrepo/files/01-setup-schema.sql +++ b/helm/dbrepo/files/01-setup-schema.sql @@ -280,6 +280,7 @@ CREATE TABLE IF NOT EXISTS `mdb_view` last_modified TIMESTAMP, owned_by VARCHAR(36) NOT NULL, PRIMARY KEY (`id`), + UNIQUE (`vdbid`, `internal_name`), FOREIGN KEY (`vdbid`) REFERENCES mdb_databases (`id`), FOREIGN KEY (`owned_by`) REFERENCES mdb_users (`id`) ) WITH SYSTEM VERSIONING; @@ -596,32 +597,14 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Equal operator', '=', ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Greater than or equal operator', '>=', 'https://mariadb.com/kb/en/greater-than-or-equal/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Not equal operator', '!=', 'https://mariadb.com/kb/en/not-equal/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Addition operator', '+', - 'https://mariadb.com/kb/en/addition-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Division operator', '/', - 'https://mariadb.com/kb/en/division-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Modulo operator', '%', 'https://mariadb.com/kb/en/modulo-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Multiplication operator', '*', - 'https://mariadb.com/kb/en/multiplication-operator/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Subtraction operator', '-', - 'https://mariadb.com/kb/en/subtraction-operator-/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LIKE', 'LIKE', 'https://mariadb.com/kb/en/like/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT LIKE', 'NOT LIKE', 'https://mariadb.com/kb/en/not-like/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IN', 'IN', 'https://mariadb.com/kb/en/in/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT IN', 'NOT IN', 'https://mariadb.com/kb/en/not-in/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS', 'IS', 'https://mariadb.com/kb/en/is/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NOT', 'IS NOT', 'https://mariadb.com/kb/en/is-not/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NOT NULL', 'IS NOT NULL', 'https://mariadb.com/kb/en/is-not-null/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'IS NULL', 'IS NULL', 'https://mariadb.com/kb/en/is-null/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ISNULL', 'ISNULL', 'https://mariadb.com/kb/en/isnull/'), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'REGEXP', 'REGEXP', 'https://mariadb.com/kb/en/regexp/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT REGEXP', 'NOT REGEXP', 'https://mariadb.com/kb/en/not-regexp/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise AND', '&', 'https://mariadb.com/kb/en/bitwise_and/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise OR', '|', 'https://mariadb.com/kb/en/bitwise-or/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise XOR', '^', 'https://mariadb.com/kb/en/bitwise-xor/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Bitwise NOT', '~', 'https://mariadb.com/kb/en/bitwise-not/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Left shift', '<<', 'https://mariadb.com/kb/en/shift-left/'), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'Right shift', '>>', 'https://mariadb.com/kb/en/shift-right/'); + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'NOT REGEXP', 'NOT REGEXP', 'https://mariadb.com/kb/en/not-regexp/'); INSERT INTO `mdb_ontologies` (prefix, uri, uri_pattern, sparql_endpoint, rdf_path) diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar index 7072823dcbcc2d91dab2624b91f1e47fad47dbff..1d72200c19c7b9fb124773e3ffc0249d1b535e2f 100644 Binary files a/helm/dbrepo/files/create-event-listener.jar and b/helm/dbrepo/files/create-event-listener.jar differ diff --git a/lib/python/coverage.xml b/lib/python/coverage.xml index 4c3ca2d8955982cd6cfb705f5b102bf28d8d0be2..ac21b0bc1ed6b9f659ba578333c89e481c34ca8f 100644 --- a/lib/python/coverage.xml +++ b/lib/python/coverage.xml @@ -1,14 +1,14 @@ <?xml version="1.0" ?> -<coverage version="7.6.12" timestamp="1740131337201" lines-valid="1752" lines-covered="1699" line-rate="0.9697" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> - <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.6.12 --> +<coverage version="7.6.10" timestamp="1740478405603" lines-valid="1820" lines-covered="1743" line-rate="0.9577" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> + <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.6.10 --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> <source>/home/mweise/Projects/fda-services/lib/python</source> </sources> <packages> - <package name="dbrepo" line-rate="0.9376" branch-rate="0" complexity="0"> + <package name="dbrepo" line-rate="0.9134" branch-rate="0" complexity="0"> <classes> - <class name="RestClient.py" filename="dbrepo/RestClient.py" complexity="0" line-rate="0.9503" branch-rate="0"> + <class name="RestClient.py" filename="dbrepo/RestClient.py" complexity="0" line-rate="0.9248" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -783,27 +783,20 @@ <line number="1679" hits="1"/> <line number="1680" hits="1"/> <line number="1683" hits="1"/> - <line number="1689" hits="1"/> - <line number="1690" hits="1"/> - <line number="1691" hits="1"/> - <line number="1692" hits="1"/> - <line number="1693" hits="1"/> - <line number="1694" hits="1"/> + <line number="1689" hits="0"/> + <line number="1690" hits="0"/> + <line number="1691" hits="0"/> + <line number="1692" hits="0"/> + <line number="1693" hits="0"/> + <line number="1694" hits="0"/> <line number="1697" hits="1"/> - <line number="1716" hits="1"/> - <line number="1717" hits="1"/> - <line number="1718" hits="1"/> - <line number="1719" hits="1"/> - <line number="1720" hits="1"/> - <line number="1721" hits="1"/> - <line number="1722" hits="1"/> - <line number="1723" hits="1"/> - <line number="1724" hits="1"/> - <line number="1725" hits="1"/> - <line number="1726" hits="1"/> - <line number="1727" hits="1"/> - <line number="1728" hits="1"/> - <line number="1729" hits="1"/> + <line number="1703" hits="1"/> + <line number="1704" hits="1"/> + <line number="1705" hits="1"/> + <line number="1706" hits="1"/> + <line number="1707" hits="1"/> + <line number="1708" hits="1"/> + <line number="1711" hits="1"/> <line number="1730" hits="1"/> <line number="1731" hits="1"/> <line number="1732" hits="1"/> @@ -818,24 +811,70 @@ <line number="1741" hits="1"/> <line number="1742" hits="1"/> <line number="1743" hits="1"/> + <line number="1744" hits="1"/> <line number="1745" hits="1"/> + <line number="1746" hits="1"/> + <line number="1747" hits="1"/> <line number="1748" hits="1"/> - <line number="1768" hits="1"/> - <line number="1769" hits="1"/> - <line number="1771" hits="1"/> - <line number="1772" hits="1"/> - <line number="1773" hits="1"/> - <line number="1774" hits="1"/> - <line number="1775" hits="1"/> - <line number="1776" hits="1"/> - <line number="1777" hits="1"/> - <line number="1778" hits="1"/> - <line number="1779" hits="1"/> - <line number="1780" hits="1"/> - <line number="1781" hits="1"/> - <line number="1782" hits="1"/> + <line number="1749" hits="1"/> + <line number="1750" hits="1"/> + <line number="1751" hits="1"/> + <line number="1752" hits="1"/> + <line number="1753" hits="1"/> + <line number="1754" hits="1"/> + <line number="1755" hits="1"/> + <line number="1756" hits="1"/> + <line number="1757" hits="1"/> + <line number="1759" hits="1"/> + <line number="1762" hits="1"/> + <line number="1773" hits="0"/> + <line number="1774" hits="0"/> + <line number="1775" hits="0"/> + <line number="1776" hits="0"/> + <line number="1777" hits="0"/> + <line number="1778" hits="0"/> + <line number="1779" hits="0"/> + <line number="1780" hits="0"/> <line number="1783" hits="1"/> - <line number="1784" hits="1"/> + <line number="1794" hits="0"/> + <line number="1795" hits="0"/> + <line number="1796" hits="0"/> + <line number="1797" hits="0"/> + <line number="1798" hits="0"/> + <line number="1799" hits="0"/> + <line number="1800" hits="0"/> + <line number="1801" hits="0"/> + <line number="1804" hits="1"/> + <line number="1810" hits="1"/> + <line number="1811" hits="1"/> + <line number="1812" hits="1"/> + <line number="1813" hits="1"/> + <line number="1814" hits="1"/> + <line number="1815" hits="0"/> + <line number="1818" hits="1"/> + <line number="1824" hits="1"/> + <line number="1825" hits="1"/> + <line number="1826" hits="1"/> + <line number="1827" hits="1"/> + <line number="1828" hits="1"/> + <line number="1829" hits="0"/> + <line number="1833" hits="1"/> + <line number="1853" hits="1"/> + <line number="1854" hits="1"/> + <line number="1856" hits="1"/> + <line number="1857" hits="1"/> + <line number="1858" hits="1"/> + <line number="1859" hits="1"/> + <line number="1860" hits="1"/> + <line number="1861" hits="1"/> + <line number="1862" hits="1"/> + <line number="1863" hits="1"/> + <line number="1864" hits="1"/> + <line number="1865" hits="1"/> + <line number="1866" hits="1"/> + <line number="1867" hits="1"/> + <line number="1868" hits="1"/> + <line number="1869" hits="1"/> </lines> </class> <class name="UploadClient.py" filename="dbrepo/UploadClient.py" complexity="0" line-rate="0.52" branch-rate="0"> @@ -895,44 +934,44 @@ <line number="17" hits="1"/> <line number="18" hits="1"/> <line number="19" hits="1"/> - <line number="20" hits="1"/> - <line number="21" hits="1"/> <line number="22" hits="1"/> <line number="23" hits="1"/> <line number="24" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="1"/> <line number="27" hits="1"/> <line number="28" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> <line number="33" hits="1"/> - <line number="34" hits="1"/> - <line number="35" hits="1"/> <line number="36" hits="1"/> <line number="37" hits="1"/> + <line number="38" hits="1"/> + <line number="39" hits="1"/> <line number="40" hits="1"/> - <line number="41" hits="1"/> - <line number="42" hits="1"/> + <line number="43" hits="1"/> + <line number="44" hits="1"/> <line number="45" hits="1"/> <line number="46" hits="1"/> <line number="47" hits="1"/> - <line number="48" hits="1"/> - <line number="49" hits="1"/> <line number="50" hits="1"/> <line number="51" hits="1"/> <line number="52" hits="1"/> - <line number="53" hits="1"/> + <line number="55" hits="1"/> <line number="56" hits="1"/> <line number="57" hits="1"/> <line number="58" hits="1"/> <line number="59" hits="1"/> + <line number="60" hits="1"/> + <line number="61" hits="1"/> <line number="62" hits="1"/> <line number="63" hits="1"/> - <line number="64" hits="1"/> - <line number="65" hits="1"/> <line number="66" hits="1"/> <line number="67" hits="1"/> <line number="68" hits="1"/> - <line number="71" hits="1"/> + <line number="69" hits="1"/> <line number="72" hits="1"/> <line number="73" hits="1"/> <line number="74" hits="1"/> @@ -948,7 +987,7 @@ <line number="86" hits="1"/> <line number="87" hits="1"/> <line number="88" hits="1"/> - <line number="89" hits="1"/> + <line number="91" hits="1"/> <line number="92" hits="1"/> <line number="93" hits="1"/> <line number="94" hits="1"/> @@ -956,7 +995,7 @@ <line number="96" hits="1"/> <line number="97" hits="1"/> <line number="98" hits="1"/> - <line number="101" hits="1"/> + <line number="99" hits="1"/> <line number="102" hits="1"/> <line number="103" hits="1"/> <line number="104" hits="1"/> @@ -972,16 +1011,16 @@ <line number="116" hits="1"/> <line number="117" hits="1"/> <line number="118" hits="1"/> - <line number="119" hits="1"/> - <line number="120" hits="1"/> + <line number="121" hits="1"/> + <line number="122" hits="1"/> <line number="123" hits="1"/> <line number="124" hits="1"/> <line number="125" hits="1"/> <line number="126" hits="1"/> <line number="127" hits="1"/> + <line number="128" hits="1"/> + <line number="129" hits="1"/> <line number="130" hits="1"/> - <line number="131" hits="1"/> - <line number="132" hits="1"/> <line number="133" hits="1"/> <line number="134" hits="1"/> <line number="135" hits="1"/> @@ -989,26 +1028,24 @@ <line number="137" hits="1"/> <line number="140" hits="1"/> <line number="141" hits="1"/> + <line number="142" hits="1"/> + <line number="143" hits="1"/> <line number="144" hits="1"/> <line number="145" hits="1"/> - <line number="148" hits="1"/> - <line number="152" hits="1"/> - <line number="153" hits="1"/> + <line number="146" hits="1"/> + <line number="147" hits="1"/> + <line number="150" hits="1"/> + <line number="151" hits="1"/> + <line number="154" hits="1"/> <line number="155" hits="1"/> - <line number="156" hits="1"/> <line number="158" hits="1"/> - <line number="159" hits="1"/> <line number="162" hits="1"/> + <line number="163" hits="1"/> + <line number="165" hits="1"/> <line number="166" hits="1"/> - <line number="167" hits="1"/> <line number="168" hits="1"/> <line number="169" hits="1"/> - <line number="170" hits="1"/> - <line number="171" hits="1"/> <line number="172" hits="1"/> - <line number="173" hits="1"/> - <line number="174" hits="1"/> - <line number="175" hits="1"/> <line number="176" hits="1"/> <line number="177" hits="1"/> <line number="178" hits="1"/> @@ -1029,17 +1066,17 @@ <line number="193" hits="1"/> <line number="194" hits="1"/> <line number="195" hits="1"/> + <line number="196" hits="1"/> + <line number="197" hits="1"/> <line number="198" hits="1"/> + <line number="199" hits="1"/> + <line number="200" hits="1"/> + <line number="201" hits="1"/> <line number="202" hits="1"/> <line number="203" hits="1"/> <line number="204" hits="1"/> <line number="205" hits="1"/> - <line number="206" hits="1"/> - <line number="207" hits="1"/> <line number="208" hits="1"/> - <line number="209" hits="1"/> - <line number="210" hits="1"/> - <line number="211" hits="1"/> <line number="212" hits="1"/> <line number="213" hits="1"/> <line number="214" hits="1"/> @@ -1214,41 +1251,43 @@ <line number="383" hits="1"/> <line number="384" hits="1"/> <line number="385" hits="1"/> + <line number="386" hits="1"/> + <line number="387" hits="1"/> <line number="388" hits="1"/> <line number="389" hits="1"/> <line number="390" hits="1"/> + <line number="391" hits="1"/> + <line number="392" hits="1"/> <line number="393" hits="1"/> <line number="394" hits="1"/> - <line number="397" hits="1"/> + <line number="395" hits="1"/> <line number="398" hits="1"/> - <line number="401" hits="1"/> - <line number="405" hits="1"/> - <line number="406" hits="1"/> + <line number="399" hits="1"/> + <line number="400" hits="1"/> + <line number="403" hits="1"/> + <line number="404" hits="1"/> <line number="407" hits="1"/> <line number="408" hits="1"/> <line number="411" hits="1"/> - <line number="412" hits="1"/> - <line number="413" hits="1"/> - <line number="414" hits="1"/> + <line number="415" hits="1"/> + <line number="416" hits="1"/> <line number="417" hits="1"/> <line number="418" hits="1"/> <line number="421" hits="1"/> <line number="422" hits="1"/> <line number="423" hits="1"/> <line number="424" hits="1"/> - <line number="425" hits="1"/> + <line number="427" hits="1"/> <line number="428" hits="1"/> - <line number="429" hits="1"/> - <line number="430" hits="1"/> <line number="431" hits="1"/> + <line number="432" hits="1"/> + <line number="433" hits="1"/> <line number="434" hits="1"/> <line number="435" hits="1"/> <line number="438" hits="1"/> <line number="439" hits="1"/> <line number="440" hits="1"/> <line number="441" hits="1"/> - <line number="442" hits="1"/> - <line number="443" hits="1"/> <line number="444" hits="1"/> <line number="445" hits="1"/> <line number="448" hits="1"/> @@ -1258,8 +1297,10 @@ <line number="452" hits="1"/> <line number="453" hits="1"/> <line number="454" hits="1"/> - <line number="457" hits="1"/> + <line number="455" hits="1"/> <line number="458" hits="1"/> + <line number="459" hits="1"/> + <line number="460" hits="1"/> <line number="461" hits="1"/> <line number="462" hits="1"/> <line number="463" hits="1"/> @@ -1269,127 +1310,125 @@ <line number="471" hits="1"/> <line number="472" hits="1"/> <line number="473" hits="1"/> - <line number="476" hits="1"/> + <line number="474" hits="1"/> <line number="477" hits="1"/> + <line number="478" hits="1"/> + <line number="479" hits="1"/> <line number="480" hits="1"/> <line number="481" hits="1"/> <line number="482" hits="1"/> <line number="483" hits="1"/> - <line number="484" hits="1"/> - <line number="485" hits="1"/> - <line number="488" hits="1"/> - <line number="489" hits="1"/> + <line number="486" hits="1"/> + <line number="487" hits="1"/> <line number="490" hits="1"/> - <line number="493" hits="1"/> - <line number="494" hits="1"/> + <line number="491" hits="1"/> + <line number="492" hits="1"/> <line number="495" hits="1"/> - <line number="498" hits="1"/> + <line number="496" hits="1"/> <line number="499" hits="1"/> + <line number="500" hits="1"/> + <line number="501" hits="1"/> <line number="502" hits="1"/> <line number="503" hits="1"/> <line number="504" hits="1"/> - <line number="505" hits="1"/> - <line number="506" hits="1"/> <line number="507" hits="1"/> <line number="508" hits="1"/> - <line number="511" hits="1"/> + <line number="509" hits="1"/> <line number="512" hits="1"/> <line number="513" hits="1"/> <line number="514" hits="1"/> - <line number="515" hits="1"/> - <line number="516" hits="1"/> <line number="517" hits="1"/> <line number="518" hits="1"/> - <line number="519" hits="1"/> - <line number="520" hits="1"/> <line number="521" hits="1"/> <line number="522" hits="1"/> + <line number="523" hits="1"/> + <line number="524" hits="1"/> <line number="525" hits="1"/> <line number="526" hits="1"/> <line number="527" hits="1"/> - <line number="528" hits="1"/> - <line number="529" hits="1"/> + <line number="530" hits="1"/> + <line number="531" hits="1"/> <line number="532" hits="1"/> + <line number="533" hits="1"/> + <line number="534" hits="1"/> + <line number="535" hits="1"/> <line number="536" hits="1"/> <line number="537" hits="1"/> <line number="538" hits="1"/> <line number="539" hits="1"/> - <line number="542" hits="1"/> + <line number="540" hits="1"/> + <line number="541" hits="1"/> + <line number="544" hits="1"/> + <line number="545" hits="1"/> <line number="546" hits="1"/> <line number="547" hits="1"/> <line number="548" hits="1"/> <line number="551" hits="1"/> - <line number="552" hits="1"/> - <line number="553" hits="1"/> - <line number="554" hits="1"/> <line number="555" hits="1"/> <line number="556" hits="1"/> <line number="557" hits="1"/> <line number="558" hits="1"/> - <line number="559" hits="1"/> - <line number="560" hits="1"/> <line number="561" hits="1"/> - <line number="562" hits="1"/> - <line number="563" hits="1"/> + <line number="565" hits="1"/> <line number="566" hits="1"/> <line number="567" hits="1"/> - <line number="568" hits="1"/> - <line number="569" hits="1"/> <line number="570" hits="1"/> <line number="571" hits="1"/> <line number="572" hits="1"/> <line number="573" hits="1"/> <line number="574" hits="1"/> + <line number="575" hits="1"/> + <line number="576" hits="1"/> <line number="577" hits="1"/> <line number="578" hits="1"/> <line number="579" hits="1"/> <line number="580" hits="1"/> <line number="581" hits="1"/> <line number="582" hits="1"/> - <line number="583" hits="1"/> - <line number="584" hits="1"/> <line number="585" hits="1"/> <line number="586" hits="1"/> <line number="587" hits="1"/> <line number="588" hits="1"/> + <line number="589" hits="1"/> + <line number="590" hits="1"/> <line number="591" hits="1"/> <line number="592" hits="1"/> - <line number="595" hits="1"/> + <line number="593" hits="1"/> <line number="596" hits="1"/> <line number="597" hits="1"/> <line number="598" hits="1"/> <line number="599" hits="1"/> + <line number="600" hits="1"/> + <line number="601" hits="1"/> <line number="602" hits="1"/> <line number="603" hits="1"/> <line number="604" hits="1"/> <line number="605" hits="1"/> - <line number="608" hits="1"/> - <line number="609" hits="1"/> - <line number="612" hits="1"/> - <line number="613" hits="1"/> + <line number="606" hits="1"/> + <line number="607" hits="1"/> + <line number="610" hits="1"/> + <line number="611" hits="1"/> <line number="614" hits="1"/> <line number="615" hits="1"/> <line number="616" hits="1"/> <line number="617" hits="1"/> <line number="618" hits="1"/> - <line number="619" hits="1"/> - <line number="620" hits="1"/> <line number="621" hits="1"/> <line number="622" hits="1"/> <line number="623" hits="1"/> <line number="624" hits="1"/> - <line number="625" hits="1"/> - <line number="626" hits="1"/> <line number="627" hits="1"/> <line number="628" hits="1"/> - <line number="629" hits="1"/> - <line number="630" hits="1"/> <line number="631" hits="1"/> <line number="632" hits="1"/> <line number="633" hits="1"/> <line number="634" hits="1"/> + <line number="635" hits="1"/> + <line number="636" hits="1"/> <line number="637" hits="1"/> <line number="638" hits="1"/> + <line number="639" hits="1"/> + <line number="640" hits="1"/> <line number="641" hits="1"/> <line number="642" hits="1"/> <line number="643" hits="1"/> @@ -1403,12 +1442,8 @@ <line number="651" hits="1"/> <line number="652" hits="1"/> <line number="653" hits="1"/> - <line number="654" hits="1"/> - <line number="655" hits="1"/> <line number="656" hits="1"/> <line number="657" hits="1"/> - <line number="658" hits="1"/> - <line number="659" hits="1"/> <line number="660" hits="1"/> <line number="661" hits="1"/> <line number="662" hits="1"/> @@ -1416,6 +1451,8 @@ <line number="664" hits="1"/> <line number="665" hits="1"/> <line number="666" hits="1"/> + <line number="667" hits="1"/> + <line number="668" hits="1"/> <line number="669" hits="1"/> <line number="670" hits="1"/> <line number="671" hits="1"/> @@ -1429,10 +1466,10 @@ <line number="679" hits="1"/> <line number="680" hits="1"/> <line number="681" hits="1"/> + <line number="682" hits="1"/> + <line number="683" hits="1"/> <line number="684" hits="1"/> <line number="685" hits="1"/> - <line number="686" hits="1"/> - <line number="687" hits="1"/> <line number="688" hits="1"/> <line number="689" hits="1"/> <line number="690" hits="1"/> @@ -1440,13 +1477,15 @@ <line number="692" hits="1"/> <line number="693" hits="1"/> <line number="694" hits="1"/> - <line number="695" hits="1"/> - <line number="696" hits="1"/> + <line number="697" hits="1"/> + <line number="698" hits="1"/> <line number="699" hits="1"/> <line number="700" hits="1"/> <line number="701" hits="1"/> <line number="702" hits="1"/> <line number="703" hits="1"/> + <line number="704" hits="1"/> + <line number="705" hits="1"/> <line number="706" hits="1"/> <line number="707" hits="1"/> <line number="708" hits="1"/> @@ -1462,68 +1501,67 @@ <line number="720" hits="1"/> <line number="721" hits="1"/> <line number="722" hits="1"/> - <line number="725" hits="1"/> - <line number="726" hits="1"/> + <line number="723" hits="1"/> + <line number="724" hits="1"/> <line number="727" hits="1"/> <line number="728" hits="1"/> <line number="729" hits="1"/> - <line number="732" hits="1"/> - <line number="733" hits="1"/> + <line number="730" hits="1"/> + <line number="731" hits="1"/> <line number="734" hits="1"/> <line number="735" hits="1"/> - <line number="738" hits="1"/> - <line number="739" hits="1"/> + <line number="736" hits="1"/> + <line number="737" hits="1"/> + <line number="740" hits="1"/> + <line number="741" hits="1"/> <line number="742" hits="1"/> <line number="743" hits="1"/> <line number="744" hits="1"/> <line number="745" hits="1"/> <line number="746" hits="1"/> <line number="747" hits="1"/> + <line number="748" hits="1"/> + <line number="749" hits="1"/> <line number="750" hits="1"/> - <line number="751" hits="1"/> - <line number="752" hits="1"/> <line number="753" hits="1"/> + <line number="754" hits="1"/> + <line number="755" hits="1"/> <line number="756" hits="1"/> <line number="757" hits="1"/> <line number="760" hits="1"/> <line number="761" hits="1"/> <line number="762" hits="1"/> <line number="763" hits="1"/> - <line number="764" hits="1"/> + <line number="766" hits="1"/> <line number="767" hits="1"/> - <line number="768" hits="1"/> + <line number="770" hits="1"/> <line number="771" hits="1"/> + <line number="772" hits="1"/> + <line number="773" hits="1"/> + <line number="774" hits="1"/> <line number="775" hits="1"/> - <line number="776" hits="1"/> - <line number="777" hits="1"/> <line number="778" hits="1"/> + <line number="779" hits="1"/> + <line number="780" hits="1"/> <line number="781" hits="1"/> + <line number="784" hits="1"/> <line number="785" hits="1"/> - <line number="786" hits="1"/> + <line number="788" hits="1"/> <line number="789" hits="1"/> - <line number="793" hits="1"/> - <line number="794" hits="1"/> + <line number="790" hits="1"/> + <line number="791" hits="1"/> + <line number="792" hits="1"/> <line number="795" hits="1"/> <line number="796" hits="1"/> - <line number="797" hits="1"/> - <line number="798" hits="1"/> <line number="799" hits="1"/> - <line number="800" hits="1"/> - <line number="801" hits="1"/> - <line number="802" hits="1"/> <line number="803" hits="1"/> <line number="804" hits="1"/> <line number="805" hits="1"/> <line number="806" hits="1"/> - <line number="807" hits="1"/> - <line number="808" hits="1"/> <line number="809" hits="1"/> - <line number="810" hits="1"/> <line number="813" hits="1"/> + <line number="814" hits="1"/> <line number="817" hits="1"/> - <line number="818" hits="1"/> - <line number="819" hits="1"/> - <line number="820" hits="1"/> <line number="821" hits="1"/> <line number="822" hits="1"/> <line number="823" hits="1"/> @@ -1542,37 +1580,46 @@ <line number="836" hits="1"/> <line number="837" hits="1"/> <line number="838" hits="1"/> - <line number="839" hits="1"/> - <line number="840" hits="1"/> <line number="841" hits="1"/> - <line number="842" hits="1"/> - <line number="843" hits="1"/> - <line number="844" hits="1"/> <line number="845" hits="1"/> <line number="846" hits="1"/> <line number="847" hits="1"/> <line number="848" hits="1"/> <line number="849" hits="1"/> <line number="850" hits="1"/> + <line number="851" hits="1"/> + <line number="852" hits="1"/> <line number="853" hits="1"/> + <line number="854" hits="1"/> + <line number="855" hits="1"/> + <line number="856" hits="1"/> <line number="857" hits="1"/> <line number="858" hits="1"/> <line number="859" hits="1"/> <line number="860" hits="1"/> <line number="861" hits="1"/> <line number="862" hits="1"/> + <line number="863" hits="1"/> + <line number="864" hits="1"/> <line number="865" hits="1"/> + <line number="866" hits="1"/> + <line number="867" hits="1"/> + <line number="868" hits="1"/> <line number="869" hits="1"/> <line number="870" hits="1"/> + <line number="871" hits="1"/> <line number="872" hits="1"/> <line number="873" hits="1"/> + <line number="874" hits="1"/> + <line number="875" hits="1"/> <line number="876" hits="1"/> - <line number="880" hits="1"/> + <line number="877" hits="1"/> + <line number="878" hits="1"/> <line number="881" hits="1"/> - <line number="883" hits="1"/> - <line number="884" hits="1"/> + <line number="885" hits="1"/> <line number="886" hits="1"/> <line number="887" hits="1"/> + <line number="888" hits="1"/> <line number="889" hits="1"/> <line number="890" hits="1"/> <line number="893" hits="1"/> @@ -1590,29 +1637,19 @@ <line number="917" hits="1"/> <line number="918" hits="1"/> <line number="921" hits="1"/> - <line number="922" hits="1"/> - <line number="923" hits="1"/> - <line number="924" hits="1"/> <line number="925" hits="1"/> <line number="926" hits="1"/> - <line number="927" hits="1"/> <line number="928" hits="1"/> <line number="929" hits="1"/> - <line number="930" hits="1"/> - <line number="931" hits="1"/> <line number="932" hits="1"/> - <line number="933" hits="1"/> <line number="936" hits="1"/> <line number="937" hits="1"/> + <line number="939" hits="1"/> <line number="940" hits="1"/> - <line number="941" hits="1"/> <line number="942" hits="1"/> <line number="943" hits="1"/> - <line number="944" hits="1"/> <line number="945" hits="1"/> <line number="946" hits="1"/> - <line number="947" hits="1"/> - <line number="948" hits="1"/> <line number="949" hits="1"/> <line number="950" hits="1"/> <line number="951" hits="1"/> @@ -1620,26 +1657,20 @@ <line number="953" hits="1"/> <line number="954" hits="1"/> <line number="955" hits="1"/> + <line number="956" hits="1"/> + <line number="957" hits="1"/> <line number="958" hits="1"/> <line number="959" hits="1"/> <line number="960" hits="1"/> <line number="961" hits="1"/> - <line number="962" hits="1"/> - <line number="963" hits="1"/> <line number="964" hits="1"/> <line number="965" hits="1"/> - <line number="966" hits="1"/> - <line number="967" hits="1"/> <line number="968" hits="1"/> <line number="969" hits="1"/> <line number="970" hits="1"/> - <line number="971" hits="1"/> - <line number="972" hits="1"/> <line number="973" hits="1"/> <line number="974" hits="1"/> <line number="975" hits="1"/> - <line number="976" hits="1"/> - <line number="977" hits="1"/> <line number="978" hits="1"/> <line number="979" hits="1"/> <line number="980" hits="1"/> @@ -1647,6 +1678,8 @@ <line number="982" hits="1"/> <line number="983" hits="1"/> <line number="984" hits="1"/> + <line number="985" hits="1"/> + <line number="986" hits="1"/> <line number="987" hits="1"/> <line number="988" hits="1"/> <line number="989" hits="1"/> @@ -1655,8 +1688,6 @@ <line number="992" hits="1"/> <line number="993" hits="1"/> <line number="994" hits="1"/> - <line number="995" hits="1"/> - <line number="996" hits="1"/> <line number="997" hits="1"/> <line number="998" hits="1"/> <line number="999" hits="1"/> @@ -1664,6 +1695,8 @@ <line number="1001" hits="1"/> <line number="1002" hits="1"/> <line number="1003" hits="1"/> + <line number="1004" hits="1"/> + <line number="1005" hits="1"/> <line number="1006" hits="1"/> <line number="1007" hits="1"/> <line number="1008" hits="1"/> @@ -1682,8 +1715,8 @@ <line number="1021" hits="1"/> <line number="1022" hits="1"/> <line number="1023" hits="1"/> - <line number="1024" hits="1"/> - <line number="1025" hits="1"/> + <line number="1026" hits="1"/> + <line number="1027" hits="1"/> <line number="1028" hits="1"/> <line number="1029" hits="1"/> <line number="1030" hits="1"/> @@ -1695,10 +1728,10 @@ <line number="1036" hits="1"/> <line number="1037" hits="1"/> <line number="1038" hits="1"/> + <line number="1039" hits="1"/> + <line number="1040" hits="1"/> <line number="1041" hits="1"/> <line number="1042" hits="1"/> - <line number="1043" hits="1"/> - <line number="1044" hits="1"/> <line number="1045" hits="1"/> <line number="1046" hits="1"/> <line number="1047" hits="1"/> @@ -1713,6 +1746,8 @@ <line number="1056" hits="1"/> <line number="1057" hits="1"/> <line number="1058" hits="1"/> + <line number="1059" hits="1"/> + <line number="1060" hits="1"/> <line number="1061" hits="1"/> <line number="1062" hits="1"/> <line number="1063" hits="1"/> @@ -1722,14 +1757,21 @@ <line number="1069" hits="1"/> <line number="1070" hits="1"/> <line number="1071" hits="1"/> + <line number="1072" hits="1"/> + <line number="1073" hits="1"/> <line number="1074" hits="1"/> - <line number="1078" hits="1"/> - <line number="1079" hits="1"/> + <line number="1075" hits="1"/> + <line number="1076" hits="1"/> + <line number="1077" hits="1"/> <line number="1080" hits="1"/> <line number="1081" hits="1"/> <line number="1082" hits="1"/> + <line number="1083" hits="1"/> + <line number="1084" hits="1"/> <line number="1085" hits="1"/> <line number="1086" hits="1"/> + <line number="1087" hits="1"/> + <line number="1088" hits="1"/> <line number="1089" hits="1"/> <line number="1090" hits="1"/> <line number="1091" hits="1"/> @@ -1738,21 +1780,47 @@ <line number="1094" hits="1"/> <line number="1095" hits="1"/> <line number="1096" hits="1"/> - <line number="1099" hits="1"/> + <line number="1097" hits="1"/> <line number="1100" hits="1"/> <line number="1101" hits="1"/> <line number="1102" hits="1"/> <line number="1103" hits="1"/> - <line number="1104" hits="1"/> + <line number="1106" hits="1"/> <line number="1107" hits="1"/> <line number="1108" hits="1"/> <line number="1109" hits="1"/> <line number="1110" hits="1"/> <line number="1113" hits="1"/> - <line number="1114" hits="1"/> - <line number="1115" hits="1"/> - <line number="1116" hits="1"/> <line number="1117" hits="1"/> + <line number="1118" hits="1"/> + <line number="1119" hits="1"/> + <line number="1120" hits="1"/> + <line number="1121" hits="1"/> + <line number="1124" hits="1"/> + <line number="1125" hits="1"/> + <line number="1128" hits="1"/> + <line number="1129" hits="1"/> + <line number="1130" hits="1"/> + <line number="1131" hits="1"/> + <line number="1132" hits="1"/> + <line number="1133" hits="1"/> + <line number="1134" hits="1"/> + <line number="1135" hits="1"/> + <line number="1138" hits="1"/> + <line number="1139" hits="1"/> + <line number="1140" hits="1"/> + <line number="1141" hits="1"/> + <line number="1142" hits="1"/> + <line number="1143" hits="1"/> + <line number="1146" hits="1"/> + <line number="1147" hits="1"/> + <line number="1148" hits="1"/> + <line number="1149" hits="1"/> + <line number="1152" hits="1"/> + <line number="1153" hits="1"/> + <line number="1154" hits="1"/> + <line number="1155" hits="1"/> + <line number="1156" hits="1"/> </lines> </class> <class name="exceptions.py" filename="dbrepo/api/exceptions.py" complexity="0" line-rate="1" branch-rate="0"> diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py index 76eeaa18a118fcf531901469850e60232e317a0a..1177372ba1b227a73f9a460501a8282348483348 100644 --- a/lib/python/dbrepo/RestClient.py +++ b/lib/python/dbrepo/RestClient.py @@ -11,6 +11,7 @@ from dbrepo.api.dto import * from dbrepo.api.exceptions import ResponseCodeError, NotExistsError, \ ForbiddenError, MalformedError, NameExistsError, QueryStoreError, ExternalSystemError, \ AuthenticationError, FormatNotAvailable, RequestError, ServiceError, ServiceConnectionError +from dbrepo.api.mapper import query_to_subset logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)-6s %(message)s', level=logging.INFO, stream=sys.stdout) @@ -720,13 +721,14 @@ class RestClient: raise ResponseCodeError(f'Failed to update view: response code: {response.status_code} is not ' f'202 (ACCEPTED): {response.text}') - def create_view(self, database_id: str, name: str, query: str, is_public: bool, is_schema_public: bool) -> View: + def create_view(self, database_id: str, name: str, query: QueryDefinition, is_public: bool, + is_schema_public: bool) -> ViewBrief: """ Create a view in a database with given database id. :param database_id: The database id. :param name: The name of the created view. - :param query: The query of the created view. + :param query: The query definition of the view. :param is_public: The visibility of the data. If set to true the data will be publicly visible. Optional. Default: `True`. :param is_schema_public: The visibility of the schema metadata. If set to true the schema metadata will be publicly visible. Optional. Default: `True`. @@ -740,13 +742,15 @@ class RestClient: :raises ServiceError: If something went wrong with obtaining the information in the search service. :raises ResponseCodeError: If something went wrong with the retrieval. """ + database = self.get_database(database_id=database_id) + subset = query_to_subset(database, self.get_image(database.container.image.id), query) url = f'/api/database/{database_id}/view' response = self._wrapper(method="post", url=url, force_auth=True, - payload=CreateView(name=name, query=query, is_public=is_public, + payload=CreateView(name=name, query=subset, is_public=is_public, is_schema_public=is_schema_public)) if response.status_code == 201: body = response.json() - return View.model_validate(body) + return ViewBrief.model_validate(body) if response.status_code == 400: raise MalformedError(f'Failed to create view: {response.text}') if response.status_code == 403: @@ -1300,7 +1304,7 @@ class RestClient: raise ResponseCodeError(f'Failed to delete database access: response code: {response.status_code} is not ' f'201 (CREATED): {response.text}') - def create_subset(self, database_id: str, query: str, page: int = 0, size: int = 10, + def create_subset(self, database_id: str, query: QueryDefinition, page: int = 0, size: int = 10, timestamp: datetime.datetime = None) -> DataFrame: """ Executes a SQL query in a database where the current user has at least read access with given database id. The @@ -1308,7 +1312,7 @@ class RestClient: timestamp. :param database_id: The database id. - :param query: The query statement. + :param query: The query definition. :param page: The result pagination number. Optional. Default: `0`. :param size: The result pagination size. Optional. Default: `10`. :param timestamp: The timestamp at which the data validity is set. Optional. Default: <current timestamp>. @@ -1323,15 +1327,17 @@ class RestClient: :raises ServiceError: If something went wrong with obtaining the information in the data service. :raises ResponseCodeError: If something went wrong with the retrieval. """ - url = f'/api/database/{database_id}/subset' + database = self.get_database(database_id=database_id) + subset = query_to_subset(database, self.get_image(database.container.image.id), query) params = [] if page is not None and size is not None: params.append(('page', page)) params.append(('size', size)) if timestamp is not None: params.append(('timestamp', timestamp.strftime("%Y-%m-%dT%H:%M:%SZ"))) + url = f'/api/database/{database_id}/subset' response = self._wrapper(method="post", url=url, headers={"Accept": "application/json"}, params=params, - payload=ExecuteQuery(statement=query)) + payload=subset) if response.status_code == 201: logging.info(f'Created subset with id: {response.headers["X-Id"]}') return DataFrame.from_records(response.json()) @@ -1710,7 +1716,7 @@ class RestClient: def get_identifiers(self, database_id: str = None, subset_id: str = None, view_id: str = None, table_id: str = None, type: IdentifierType = None, status: IdentifierStatusType = None) -> List[ - Identifier]: + Identifier]: """ Get list of identifiers, filter by the remaining optional arguments. @@ -1829,7 +1835,6 @@ class RestClient: raise ResponseCodeError(f'Failed to get messages: response code: {response.status_code} is not ' f'200 (OK): {response.text}') - def update_table_column(self, database_id: str, table_id: str, column_id: str, concept_uri: str = None, unit_uri: str = None) -> Column: """ diff --git a/lib/python/dbrepo/api/dto.py b/lib/python/dbrepo/api/dto.py index d004a9faa32e6e8975d8e90035fd9e403fabf556..fd378739cf5bb48501b18e32148a5d1110b9ce7f 100644 --- a/lib/python/dbrepo/api/dto.py +++ b/lib/python/dbrepo/api/dto.py @@ -12,29 +12,27 @@ Timestamp = Annotated[ ] +class Operator(BaseModel): + id: str + display_name: str + value: str + documentation: str + + class Image(BaseModel): id: str - registry: str name: str version: str - dialect: str - driver_class: str - jdbc_method: str - default_port: int + default: bool data_types: List[DataType] = field(default_factory=list) + operators: List[Operator] = field(default_factory=list) - -class Operator(BaseModel): - id: str - display_name: str - value: str - documentation: str - class ImageBrief(BaseModel): id: str name: str version: str + default: bool class CreateDatabase(BaseModel): @@ -89,8 +87,6 @@ class Container(BaseModel): id: str name: str internal_name: str - host: str - port: int image: Image ui_host: Optional[str] = None ui_port: Optional[int] = None @@ -681,6 +677,7 @@ class Identifier(BaseModel): publication_day: Optional[int] = None publication_month: Optional[int] = None + class Message(BaseModel): id: str type: str @@ -707,9 +704,9 @@ class IdentifierBrief(BaseModel): class View(BaseModel): id: str - database_id: str name: str query: str + database_id: str query_hash: str owner: UserBrief internal_name: str @@ -722,7 +719,7 @@ class View(BaseModel): class CreateView(BaseModel): name: str - query: str + query: Subset is_public: bool is_schema_public: bool @@ -788,8 +785,59 @@ class UnitBrief(BaseModel): description: Optional[str] = None -class ExecuteQuery(BaseModel): - statement: str +class FilterType(str, Enum): + """ + Enumeration of filter types. + """ + WHERE = "where" + OR = "or" + AND = "and" + + +class OrderType(str, Enum): + """ + Enumeration of order types. + """ + ASC = "asc" + DESC = "desc" + + +class Filter(BaseModel): + type: FilterType + column_id: str + operator_id: str + value: str + + +class FilterDefinition(BaseModel): + type: FilterType + column: str + operator: str + value: str + + +class Order(BaseModel): + column_id: str + direction: Optional[OrderType] = None + + +class OrderDefinition(BaseModel): + column: str + direction: Optional[OrderType] = None + + +class Subset(BaseModel): + table_id: str + columns: List[str] + filter: Optional[List[Filter]] = None + order: Optional[List[Order]] = None + + +class QueryDefinition(BaseModel): + table: str + columns: List[str] + filter: Optional[List[FilterDefinition]] = None + order: Optional[List[OrderDefinition]] = None class TitleType(str, Enum): @@ -925,23 +973,6 @@ class IdentifierStatusType(str, Enum): """The identifier is a draft and can still be edited.""" -class IdentifierType(str, Enum): - """ - Enumeration of identifier types. - """ - TABLE = "table" - """The identifier identifies a table.""" - - DATABASE = "database" - """The identifier identifies a database.""" - - VIEW = "view" - """The identifier identifies a view.""" - - SUBSET = "subset" - """The identifier identifies a subset.""" - - class Query(BaseModel): id: str owner: UserBrief @@ -1007,8 +1038,8 @@ class Column(BaseModel): median: Optional[float] = None concept: Optional[ConceptBrief] = None unit: Optional[UnitBrief] = None - enums: Optional[List[str]] = field(default_factory=list) - sets: Optional[List[str]] = field(default_factory=list) + enums: Optional[List[ColumnEnum]] = field(default_factory=list) + sets: Optional[List[ColumnSet]] = field(default_factory=list) index_length: Optional[int] = None length: Optional[int] = None data_length: Optional[int] = None diff --git a/lib/python/dbrepo/api/mapper.py b/lib/python/dbrepo/api/mapper.py new file mode 100644 index 0000000000000000000000000000000000000000..c062b29923f17f18f8a9d21f5c1913df2b3bb3d4 --- /dev/null +++ b/lib/python/dbrepo/api/mapper.py @@ -0,0 +1,40 @@ +from dbrepo.api.dto import Subset, QueryDefinition, Database, Table, Image, Filter, Order +from dbrepo.api.exceptions import MalformedError + + +def query_to_subset(database: Database, image: Image, query: QueryDefinition) -> Subset: + if len(query.columns) < 1: + raise MalformedError(f'Failed to create view: no columns selected') + tables: [Table] = [table for table in database.tables if table.internal_name == query.table] + if len(tables) != 1: + raise MalformedError(f'Failed to create view: table name not found in database') + filtered_column_ids: [str] = [column.id for column in tables[0].columns if + column.internal_name in query.columns] + if len(filtered_column_ids) != len(query.columns): + raise MalformedError(f'Failed to create view: not all columns found in database') + filters = [] + if query.filter is not None: + for filter in query.filter: + # column_id + filter_column_ids: [str] = [column.id for column in tables[0].columns if + column.internal_name == filter.column] + if len(filter_column_ids) != 1: + raise MalformedError(f'Failed to create view: filtered column name not found in database') + # operator_id + filter_ops_ids: [str] = [op.id for op in image.operators if op.value == filter.operator] + if len(filter_ops_ids) != 1: + raise MalformedError(f'Failed to create view: filter operator not found in image') + filters.append(Filter(type=filter.type, + column_id=filter_column_ids[0], + operator_id=filter_ops_ids[0], + value=filter.value)) + order = None + if query.order is not None: + for order in query.order: + # column_id + order_column_ids: [str] = [column.id for column in tables[0].columns if + column.internal_name == order.column] + if len(order_column_ids) != 1: + raise MalformedError(f'Failed to create view: order column name not found in database') + order.append(Order(column_id=order_column_ids[0].id, direction=order.direction)) + return Subset(table_id=tables[0].id, columns=filtered_column_ids, filter=filters, order=order) diff --git a/lib/python/tests/test_dtos.py b/lib/python/tests/test_dtos.py index 3f05e24081b45deb662afed4a3b342803b6ce56a..3e99135e8b97574502939204dd131730a9bd7689 100644 --- a/lib/python/tests/test_dtos.py +++ b/lib/python/tests/test_dtos.py @@ -35,9 +35,10 @@ dictConfig({ }) -class AnalyseUnitTest(unittest.TestCase): +class DtoUnitTest(unittest.TestCase): schemas = None models: [()] = [] + exclusions: [str] = ['EnumType'] found: int = 0 skipped: [str] = [] @@ -48,7 +49,7 @@ class AnalyseUnitTest(unittest.TestCase): self.found += 1 if not inspect.isclass(obj): continue - if f'{name}Dto' not in self.schemas: + if f'{name}Dto' not in self.schemas or name not in self.exclusions: logging.debug(f'skip model {name}: OpenAPI schema definition {name}Dto not found') self.skipped.append(f'{name}Dto') continue diff --git a/lib/python/tests/test_unit_container.py b/lib/python/tests/test_unit_container.py index aae90467b504b684e96b6b0c3fa314fe83445ef6..052e2aa524787184fecb72da29c677a616f2e9f4 100644 --- a/lib/python/tests/test_unit_container.py +++ b/lib/python/tests/test_unit_container.py @@ -3,7 +3,7 @@ import unittest import requests_mock from dbrepo.RestClient import RestClient -from dbrepo.api.dto import Container, Image, ContainerBrief, ImageBrief, DataType +from dbrepo.api.dto import Container, Image, ContainerBrief, ImageBrief, DataType, Operator from dbrepo.api.exceptions import ResponseCodeError, NotExistsError, AuthenticationError, MalformedError, \ ForbiddenError, NameExistsError @@ -25,8 +25,14 @@ class ContainerUnitTest(unittest.TestCase): dialect="org.hibernate.dialect.MariaDBDialect", driver_class="org.mariadb.jdbc.Driver", jdbc_method="mariadb", + default=True, + operators=[ + Operator(id="0917b17e-5d68-4ddf-94f6-f178f74a0dae", + display_name="XOR", + value="XOR", + documentation="https://mariadb.com/kb/en/xor/")], data_types=[ - DataType(id="a01957bf-6fed-46a3-8b13-dc6ea304a3af", + DataType(id="22975809-5496-4d67-9fd4-6689f0030f82", display_name="SERIAL", value="serial", documentation="https://mariadb.com/kb/en/bigint/", @@ -145,7 +151,8 @@ class ContainerUnitTest(unittest.TestCase): running=True, image=ImageBrief(id="b104648b-54d2-4d72-9834-8e0e6d428b39", name="mariadb", - version="10.11.3"), + version="10.11.3", + default=True), hash="f829dd8a884182d0da846f365dee1221fd16610a14c81b8f9f295ff162749e50") ] # mock @@ -179,8 +186,14 @@ class ContainerUnitTest(unittest.TestCase): dialect="org.hibernate.dialect.MariaDBDialect", driver_class="org.mariadb.jdbc.Driver", jdbc_method="mariadb", + default=True, + operators=[ + Operator(id="0917b17e-5d68-4ddf-94f6-f178f74a0dae", + display_name="XOR", + value="XOR", + documentation="https://mariadb.com/kb/en/xor/")], data_types=[ - DataType(id="a01957bf-6fed-46a3-8b13-dc6ea304a3af", + DataType(id="22975809-5496-4d67-9fd4-6689f0030f82", display_name="SERIAL", value="serial", documentation="https://mariadb.com/kb/en/bigint/", diff --git a/lib/python/tests/test_unit_database.py b/lib/python/tests/test_unit_database.py index 3fd7ddcd60a7c78db0bfdacdef471db19361d53e..54a41cfbd79027fad93e5b2c570110ac17a4ea8f 100644 --- a/lib/python/tests/test_unit_database.py +++ b/lib/python/tests/test_unit_database.py @@ -83,8 +83,8 @@ class DatabaseUnitTest(unittest.TestCase): image=ImageBrief( id="b104648b-54d2-4d72-9834-8e0e6d428b39", name='mariadb', - version='11.2.2' - ) + version='11.2.2', + default=True) ) ) with requests_mock.Mocker() as mock: @@ -100,7 +100,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732', status_code=403) # test try: - response = RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ForbiddenError as e: pass @@ -110,7 +110,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732', status_code=404) # test try: - response = RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except NotExistsError as e: pass @@ -120,7 +120,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732', status_code=202) # test try: - response = RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ResponseCodeError as e: pass @@ -141,8 +141,8 @@ class DatabaseUnitTest(unittest.TestCase): image=ImageBrief( id="b104648b-54d2-4d72-9834-8e0e6d428b39", name='mariadb', - version='11.2.2' - ) + version='11.2.2', + default=True) ) ) with requests_mock.Mocker() as mock: @@ -161,9 +161,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=400) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except MalformedError as e: pass @@ -173,9 +173,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=403) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except ForbiddenError as e: pass @@ -185,9 +185,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=404) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except NotExistsError as e: pass @@ -197,9 +197,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=409) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except QueryStoreError as e: pass @@ -209,9 +209,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=502) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except ServiceConnectionError as e: pass @@ -221,9 +221,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=503) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except ServiceError as e: pass @@ -233,9 +233,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=202) # test try: - response = RestClient(username="a", password="b").create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient(username="a", password="b").create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except ResponseCodeError as e: pass @@ -245,9 +245,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.post('/api/database', status_code=404) # test try: - response = RestClient().create_database(name='test', - container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", - is_public=True) + RestClient().create_database(name='test', + container_id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + is_public=True) except AuthenticationError as e: pass @@ -268,8 +268,8 @@ class DatabaseUnitTest(unittest.TestCase): image=ImageBrief( id="b104648b-54d2-4d72-9834-8e0e6d428b39", name='mariadb', - version='11.2.2' - ) + version='11.2.2', + default=True) ) ) with requests_mock.Mocker() as mock: @@ -277,10 +277,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', json=exp.model_dump(), status_code=202) # test - client = RestClient(username="a", password="b") - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + response = RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) self.assertEqual(response.is_public, True) def test_update_database_visibility_400_fails(self): @@ -289,9 +289,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=400) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except MalformedError: pass @@ -301,9 +302,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=403) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + response = RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except ForbiddenError: pass @@ -313,9 +315,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=404) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + response = RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except NotExistsError: pass @@ -325,9 +328,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=502) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except ServiceConnectionError: pass @@ -337,9 +341,10 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=503) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except ServiceError: pass @@ -349,16 +354,18 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/visibility', status_code=200) # test try: - response = RestClient(username="a", password="b").update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - is_public=True, - is_schema_public=True) + RestClient(username="a", password="b").update_database_visibility( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, + is_schema_public=True) except ResponseCodeError: pass def test_update_database_visibility_anonymous_fails(self): # test try: - response = RestClient().update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", is_public=True, is_schema_public=True) + RestClient().update_database_visibility(database_id="6bd39359-b154-456d-b9c2-caa516a45732", + is_public=True, is_schema_public=True) except AuthenticationError: pass @@ -379,8 +386,8 @@ class DatabaseUnitTest(unittest.TestCase): image=ImageBrief( id="b104648b-54d2-4d72-9834-8e0e6d428b39", name='mariadb', - version='11.2.2' - ) + version='11.2.2', + default=True) ) ) with requests_mock.Mocker() as mock: @@ -388,8 +395,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', json=exp.model_dump(), status_code=202) # test client = RestClient(username="a", password="b") - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + response = RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') self.assertEqual(response.owner.id, 'abdbf897-e599-4e5a-a3f0-7529884ea011') def test_update_database_owner_400_fails(self): @@ -398,8 +406,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=400) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except MalformedError: pass @@ -409,8 +418,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=403) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ForbiddenError: pass @@ -420,8 +430,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=404) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except NotExistsError: pass @@ -431,8 +442,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=502) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceConnectionError: pass @@ -442,8 +454,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=503) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceError: pass @@ -453,8 +466,9 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=200) # test try: - response = RestClient(username="a", password="b").update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_owner( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ResponseCodeError: pass @@ -464,8 +478,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/owner', status_code=404) # test try: - response = RestClient().update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient().update_database_owner(database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except AuthenticationError: pass @@ -484,7 +498,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', json=exp.model_dump()) mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', json=exp.model_dump()) # test - response = RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + response = RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") self.assertEqual(exp, response) def test_update_database_schema_400_fails(self): @@ -493,7 +508,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=400) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except MalformedError: pass @@ -504,7 +520,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=400) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except MalformedError: pass @@ -514,7 +531,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=403) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ForbiddenError: pass @@ -525,7 +543,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=403) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ForbiddenError: pass @@ -535,7 +554,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=404) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except NotExistsError: pass @@ -546,7 +566,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=404) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except NotExistsError: pass @@ -556,7 +577,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=502) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ServiceConnectionError: pass @@ -567,7 +589,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=502) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ServiceConnectionError: pass @@ -577,7 +600,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=503) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ServiceError: pass @@ -588,7 +612,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=503) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ServiceError: pass @@ -598,7 +623,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/table', status_code=202) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ResponseCodeError: pass @@ -609,7 +635,8 @@ class DatabaseUnitTest(unittest.TestCase): mock.put('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/metadata/view', status_code=202) # test try: - RestClient(username='foo', password='bar').update_database_schema(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient(username='foo', password='bar').update_database_schema( + database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ResponseCodeError: pass @@ -636,7 +663,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/access', status_code=403) # test try: - response = RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ForbiddenError: pass @@ -646,7 +673,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/access', status_code=404) # test try: - response = RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except NotExistsError: pass @@ -656,7 +683,7 @@ class DatabaseUnitTest(unittest.TestCase): mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/access', status_code=202) # test try: - response = RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") + RestClient().get_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732") except ResponseCodeError: pass @@ -669,9 +696,10 @@ class DatabaseUnitTest(unittest.TestCase): json=exp.model_dump(), status_code=202) # test - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + response = RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') self.assertEqual(response, exp.type) def test_create_database_access_400_fails(self): @@ -681,9 +709,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=400) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except MalformedError: pass @@ -694,8 +723,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=400) # test try: - response = RestClient().create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient().create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except AuthenticationError: pass @@ -706,9 +736,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=403) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ForbiddenError: pass @@ -719,9 +750,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=404) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except NotExistsError: pass @@ -732,9 +764,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=502) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceConnectionError: pass @@ -745,9 +778,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=503) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceError: pass @@ -758,9 +792,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=200) # test try: - response = RestClient(username="a", password="b").create_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").create_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ResponseCodeError: pass @@ -773,9 +808,10 @@ class DatabaseUnitTest(unittest.TestCase): json=exp.model_dump(), status_code=202) # test - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + response = RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') self.assertEqual(response, exp.type) def test_update_database_access_400_fails(self): @@ -785,9 +821,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=400) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except MalformedError: pass @@ -798,9 +835,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=403) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ForbiddenError: pass @@ -811,9 +849,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=404) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except NotExistsError: pass @@ -824,9 +863,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=502) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceConnectionError: pass @@ -837,9 +877,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=503) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceError: pass @@ -850,9 +891,10 @@ class DatabaseUnitTest(unittest.TestCase): status_code=200) # test try: - response = RestClient(username="a", password="b").update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").update_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ResponseCodeError: pass @@ -863,8 +905,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=404) # test try: - response = RestClient().update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", type=AccessType.READ, - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient().update_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", + type=AccessType.READ, + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except AuthenticationError: pass @@ -876,8 +919,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=202) # test client = RestClient(username="a", password="b") - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') def test_delete_database_access_400_fails(self): with requests_mock.Mocker() as mock: @@ -887,8 +931,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=400) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except MalformedError: pass @@ -900,8 +945,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=403) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ForbiddenError: pass @@ -913,8 +959,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=404) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except NotExistsError: pass @@ -926,8 +973,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=502) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceConnectionError: pass @@ -939,8 +987,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=503) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ServiceError: pass @@ -952,8 +1001,9 @@ class DatabaseUnitTest(unittest.TestCase): status_code=200) # test try: - RestClient(username="a", password="b").delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient(username="a", password="b").delete_database_access( + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except ResponseCodeError: pass @@ -965,7 +1015,8 @@ class DatabaseUnitTest(unittest.TestCase): status_code=404) # test try: - RestClient().delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') + RestClient().delete_database_access(database_id="6bd39359-b154-456d-b9c2-caa516a45732", + user_id='abdbf897-e599-4e5a-a3f0-7529884ea011') except AuthenticationError: pass diff --git a/lib/python/tests/test_unit_image.py b/lib/python/tests/test_unit_image.py index 9b994c6f1705978c30ea3f1a24f2b92500708ee6..8930303e5399184f9d976ca7eea4540c7df24541 100644 --- a/lib/python/tests/test_unit_image.py +++ b/lib/python/tests/test_unit_image.py @@ -18,9 +18,10 @@ class ImageUnitTest(unittest.TestCase): def test_get_images_succeeds(self): with requests_mock.Mocker() as mock: - exp = [ImageBrief(id="5d065194-2196-42e3-83e6-d8fc658c4b66", + exp = [ImageBrief(id="96c1876a-7473-44fd-8115-19ca6fde32d4", name="mariadb", - version="11.1.3")] + version="11.1.3", + default=False)] # mock mock.get('/api/image', json=[exp[0].model_dump()]) # test diff --git a/lib/python/tests/test_unit_messages.py b/lib/python/tests/test_unit_messages.py index 5523955c65a74ec0df5ee5ddc76d519d11269523..7d5d26e39d325d6d20587fd066d3b778bff598b6 100644 --- a/lib/python/tests/test_unit_messages.py +++ b/lib/python/tests/test_unit_messages.py @@ -18,7 +18,7 @@ class ImageUnitTest(unittest.TestCase): def test_get_images_succeeds(self): with requests_mock.Mocker() as mock: - exp = [Message(id="97e46776-aef2-4a6f-9e82-9d2ae556745f", type="info")] + exp = [Message(id="a456d7f0-9d42-48a8-bf5b-4ead85279e0e", type="info")] # mock mock.get('/api/message', json=[exp[0].model_dump()]) # test diff --git a/lib/python/tests/test_unit_query.py b/lib/python/tests/test_unit_query.py index fb23a3c9491305e6be650c81c1566a985d6c9f04..44f165b9b0ba36ab2375ddcd78c6c50cd363c7d9 100644 --- a/lib/python/tests/test_unit_query.py +++ b/lib/python/tests/test_unit_query.py @@ -6,108 +6,257 @@ import requests_mock from pandas import DataFrame from dbrepo.RestClient import RestClient -from dbrepo.api.dto import Query, QueryType, UserBrief +from dbrepo.api.dto import Query, QueryType, UserBrief, QueryDefinition, FilterDefinition, FilterType, Database, \ + ContainerBrief, ImageBrief, Image, Table, Constraints, PrimaryKey, TableBrief, ColumnBrief, ColumnType, \ + Column, Operator from dbrepo.api.exceptions import MalformedError, NotExistsError, ForbiddenError, QueryStoreError, FormatNotAvailable, \ ServiceError, ResponseCodeError, AuthenticationError class QueryUnitTest(unittest.TestCase): + database = Database( + id="6bd39359-b154-456d-b9c2-caa516a45732", + name='test', + owner=UserBrief(id='abdbf897-e599-4e5a-a3f0-7529884ea011', username='mweise'), + contact=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'), + exchange_name='dbrepo', + internal_name='test_abcd', + is_public=True, + is_schema_public=True, + tables=[Table(id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + name="Some Table", + description="Test Table", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + internal_name="some_table", + owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'), + is_versioned=True, + queue_name='test', + routing_key='dbrepo.test_database_1234.test', + is_public=True, + is_schema_public=True, + constraints=Constraints(uniques=[], + foreign_keys=[], + checks=[], + primary_key=[PrimaryKey(id="1516310f-ecb5-4614-abe2-3b96114e1484", + table=TableBrief( + id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + name='Other', + internal_name='other', + description=None, + is_versioned=True, + is_public=True, + is_schema_public=True, + owned_by='8638c043-5145-4be8-a3e4-4b79991b0a16'), + column=ColumnBrief( + id="31a533b6-8ddf-43d6-ac6a-b9da597cb976", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + name='id', + alias=None, + internal_name='id', + type=ColumnType.BIGINT))]), + columns=[Column(id="31a533b6-8ddf-43d6-ac6a-b9da597cb976", + name="ID", + ord=0, + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + internal_name="id", + type=ColumnType.BIGINT, + is_null_allowed=False), + Column(id="85de93a8-834c-4cf4-9d34-f80ebd97e606", + name="Username", + ord=1, + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + internal_name="username", + type=ColumnType.VARCHAR, + is_null_allowed=False) + ])], + container=ContainerBrief(id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + name='MariaDB Galera 11.1.3', + internal_name='mariadb', + image=ImageBrief(id="b104648b-54d2-4d72-9834-8e0e6d428b39", + name='mariadb', + version='11.2.2', + default=True))) + image = Image(id="b104648b-54d2-4d72-9834-8e0e6d428b39", + name='mariadb', + version='11.2.2', + default=True, + data_types=[], + operators=[Operator(id="6a96bd99-be3d-4d56-8c38-b14bdfead634", + display_name="IN", + value="IN", + documentation="https://mariadb.com/kb/en/in/")]) def test_create_subset_succeeds(self): with requests_mock.Mocker() as mock: exp = [{'id': 1, 'username': 'foo'}, {'id': 2, 'username': 'bar'}] df = DataFrame.from_records(json.dumps(exp)) # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', json=json.dumps(exp), + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', json=json.dumps(exp), headers={'X-Id': '1'}, status_code=201) # test client = RestClient(username="a", password="b") response = client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", page=0, size=10, timestamp=datetime.datetime(2024, 1, 1, 0, 0, 0, 0, datetime.timezone.utc), - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) self.assertTrue(DataFrame.equals(df, response)) def test_create_subset_400_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=400) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=400) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except MalformedError: pass def test_create_subset_403_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=403) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=403) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ForbiddenError: pass def test_create_subset_404_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=404) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=404) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except NotExistsError: pass def test_create_subset_417_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=417) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=417) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except QueryStoreError: pass def test_create_subset_501_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=501) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=501) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except FormatNotAvailable: pass def test_create_subset_503_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=503) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=503) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ServiceError: pass def test_create_subset_unknown_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=200) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', status_code=200) # test try: client = RestClient(username="a", password="b") client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ResponseCodeError: pass @@ -116,13 +265,22 @@ class QueryUnitTest(unittest.TestCase): exp = [{'id': 1, 'username': 'foo'}, {'id': 2, 'username': 'bar'}] df = DataFrame.from_records(json.dumps(exp)) # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', json=json.dumps(exp), + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/subset', json=json.dumps(exp), headers={'X-Id': '1'}, status_code=201) # test client = RestClient() response = client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", page=0, size=10, - query="SELECT id, username FROM some_table WHERE id IN (1,2)") + query=QueryDefinition(table="some_table", + columns=["id", "username"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) self.assertTrue(DataFrame.equals(df, response)) def test_get_subset_succeeds(self): @@ -211,7 +369,7 @@ class QueryUnitTest(unittest.TestCase): with requests_mock.Mocker() as mock: exp = [] # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', json=[]) + mock.get(f'/api/database/{self.database.id}/subset', json=[]) # test response = RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") self.assertEqual(exp, response) @@ -343,7 +501,7 @@ class QueryUnitTest(unittest.TestCase): result_number=None, identifiers=[])] # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', json=[exp[0].model_dump()]) + mock.get(f'/api/database/{self.database.id}/subset', json=[exp[0].model_dump()]) # test response = RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") self.assertEqual(exp, response) @@ -351,7 +509,7 @@ class QueryUnitTest(unittest.TestCase): def test_get_queries_403_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=403) + mock.get(f'/api/database/{self.database.id}/subset', status_code=403) # test try: RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") @@ -361,7 +519,7 @@ class QueryUnitTest(unittest.TestCase): def test_get_queries_404_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=404) + mock.get(f'/api/database/{self.database.id}/subset', status_code=404) # test try: RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") @@ -371,7 +529,7 @@ class QueryUnitTest(unittest.TestCase): def test_get_queries_503_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=503) + mock.get(f'/api/database/{self.database.id}/subset', status_code=503) # test try: RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") @@ -381,7 +539,7 @@ class QueryUnitTest(unittest.TestCase): def test_get_queries_unknown_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/subset', status_code=202) + mock.get(f'/api/database/{self.database.id}/subset', status_code=202) # test try: RestClient().get_queries(database_id="6bd39359-b154-456d-b9c2-caa516a45732") diff --git a/lib/python/tests/test_unit_view.py b/lib/python/tests/test_unit_view.py index 5792d028b37726d1c3e1f29a941387c12306cfc2..cb26eeaba8584d201202f7b6693f240b36701011 100644 --- a/lib/python/tests/test_unit_view.py +++ b/lib/python/tests/test_unit_view.py @@ -5,17 +5,94 @@ import requests_mock from pandas import DataFrame from dbrepo.RestClient import RestClient -from dbrepo.api.dto import View, ViewColumn, ColumnType, UserBrief, ViewBrief +from dbrepo.api.dto import View, ViewColumn, ColumnType, UserBrief, ViewBrief, QueryDefinition, FilterDefinition, \ + FilterType, Database, Table, Constraints, PrimaryKey, TableBrief, ColumnBrief, Column, ContainerBrief, ImageBrief, \ + Image, Operator from dbrepo.api.exceptions import ForbiddenError, NotExistsError, MalformedError, AuthenticationError, \ ResponseCodeError, ExternalSystemError, ServiceError, ServiceConnectionError class ViewUnitTest(unittest.TestCase): + database = Database( + id="6bd39359-b154-456d-b9c2-caa516a45732", + name='test', + owner=UserBrief(id='abdbf897-e599-4e5a-a3f0-7529884ea011', username='mweise'), + contact=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'), + exchange_name='dbrepo', + internal_name='test_abcd', + is_public=True, + is_schema_public=True, + tables=[Table(id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + name="Some Table", + description="Test Table", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + internal_name="some_table", + owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'), + is_versioned=True, + queue_name='test', + routing_key='dbrepo.test_database_1234.test', + is_public=True, + is_schema_public=True, + constraints=Constraints(uniques=[], + foreign_keys=[], + checks=[], + primary_key=[PrimaryKey(id="1516310f-ecb5-4614-abe2-3b96114e1484", + table=TableBrief( + id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + name='Other', + internal_name='other', + description=None, + is_versioned=True, + is_public=True, + is_schema_public=True, + owned_by='8638c043-5145-4be8-a3e4-4b79991b0a16'), + column=ColumnBrief( + id="31a533b6-8ddf-43d6-ac6a-b9da597cb976", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + name='id', + alias=None, + internal_name='id', + type=ColumnType.BIGINT))]), + columns=[Column(id="31a533b6-8ddf-43d6-ac6a-b9da597cb976", + name="ID", + ord=0, + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + internal_name="id", + type=ColumnType.BIGINT, + is_null_allowed=False), + Column(id="85de93a8-834c-4cf4-9d34-f80ebd97e606", + name="Username", + ord=1, + database_id="6bd39359-b154-456d-b9c2-caa516a45732", + table_id="029d773f-f98b-40c0-ab22-b8b1635d4fbc", + internal_name="username", + type=ColumnType.VARCHAR, + is_null_allowed=False) + ])], + container=ContainerBrief(id="44d811a8-4019-46ba-bd57-ea10a2eb0c74", + name='MariaDB Galera 11.1.3', + internal_name='mariadb', + image=ImageBrief(id="b104648b-54d2-4d72-9834-8e0e6d428b39", + name='mariadb', + version='11.2.2', + default=True))) + image = Image(id="b104648b-54d2-4d72-9834-8e0e6d428b39", + name='mariadb', + version='11.2.2', + default=True, + data_types=[], + operators=[Operator(id="6a96bd99-be3d-4d56-8c38-b14bdfead634", + display_name="IN", + value="IN", + documentation="https://mariadb.com/kb/en/in/")]) def test_get_views_empty_succeeds(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', json=[]) + mock.get(f'/api/database/{self.database.id}/view', json=[]) # test response = RestClient().get_views(database_id="6bd39359-b154-456d-b9c2-caa516a45732") self.assertEqual([], response) @@ -33,7 +110,7 @@ class ViewUnitTest(unittest.TestCase): is_public=True, is_schema_public=True)] # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', json=[exp[0].model_dump()]) + mock.get(f'/api/database/{self.database.id}/view', json=[exp[0].model_dump()]) # test response = RestClient().get_views(database_id="6bd39359-b154-456d-b9c2-caa516a45732") self.assertEqual(exp, response) @@ -41,7 +118,7 @@ class ViewUnitTest(unittest.TestCase): def test_get_views_404_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=404) + mock.get(f'/api/database/{self.database.id}/view', status_code=404) # test try: response = RestClient().get_views(database_id="6bd39359-b154-456d-b9c2-caa516a45732") @@ -51,7 +128,7 @@ class ViewUnitTest(unittest.TestCase): def test_get_views_unknown_fails(self): with requests_mock.Mocker() as mock: # mock - mock.get('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=202) + mock.get(f'/api/database/{self.database.id}/view', status_code=202) # test try: response = RestClient().get_views(database_id="6bd39359-b154-456d-b9c2-caa516a45732") @@ -192,133 +269,207 @@ class ViewUnitTest(unittest.TestCase): def test_create_view_succeeds(self): with requests_mock.Mocker() as mock: - exp = View(id="1b3449d2-780e-4683-9af0-8733e608a4aa", + exp = ViewBrief(id="1b3449d2-780e-4683-9af0-8733e608a4aa", name="Data", internal_name="data", database_id="6bd39359-b154-456d-b9c2-caa516a45732", initial_view=False, - query="SELECT id FROM mytable WHERE deg > 0", + query="SELECT id FROM some_table WHERE id IN (1,2)", query_hash="94c74728b11a690e51d64719868824735f0817b7", - owner=UserBrief(id='8638c043-5145-4be8-a3e4-4b79991b0a16', username='mweise'), + owned_by='8638c043-5145-4be8-a3e4-4b79991b0a16', is_public=True, - is_schema_public=True, - columns=[ViewColumn(id="1b3449d2-780e-4683-9af0-8733e608a4aa", - ord=0, - name="id", - internal_name="id", - database_id="6bd39359-b154-456d-b9c2-caa516a45732", - type=ColumnType.BIGINT, - is_null_allowed=False)], - identifiers=[]) + is_schema_public=True) # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', json=exp.model_dump(), status_code=201) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', json=exp.model_dump(), status_code=201) # test client = RestClient(username="a", password="b") response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) self.assertEqual(exp, response) def test_create_view_400_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=400) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=400) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except MalformedError: pass def test_create_view_403_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=403) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=403) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ForbiddenError: pass def test_create_view_404_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=404) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=404) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except NotExistsError: pass def test_create_view_423_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=423) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=423) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ExternalSystemError: pass def test_create_view_502_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=502) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=502) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ServiceConnectionError: pass def test_create_view_503_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=503) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=503) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ServiceError: pass def test_create_view_unknown_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=200) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=200) # test try: client = RestClient(username="a", password="b") - response = client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + client.create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except ResponseCodeError: pass def test_create_view_anonymous_fails(self): with requests_mock.Mocker() as mock: # mock - mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/view', status_code=404) + mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), + status_code=200) + mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), + status_code=200) + mock.post(f'/api/database/{self.database.id}/view', status_code=404) # test try: - response = RestClient().create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", - is_public=True, is_schema_public=True, - query="SELECT id FROM mytable WHERE deg > 0") + RestClient().create_view(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Data", + is_public=True, is_schema_public=True, + query=QueryDefinition(table="some_table", + columns=["id"], + filter=[ + FilterDefinition(type=FilterType.WHERE, + column="id", + operator="IN", + value="(1,2)")])) except AuthenticationError: pass