From 810371f3736fe08f3590a89dc47b88d4e85d54e6 Mon Sep 17 00:00:00 2001 From: Noah Overcash Date: Fri, 3 Nov 2023 09:47:00 -0600 Subject: [PATCH 01/16] [MODFQMMGR-72] Remove instance_title_searchable field --- .gitignore | 1 + .../db/changelog/changelog-master.xml | 1 + .../changes/v1.0.2/changelog-v1.0.2.xml | 13 + ...ldingsrecord_instance_title_searchable.xml | 48 +++ ...remove_items_instance_title_searchable.xml | 68 ++++ ...te_item_details_entity_type_definition.xml | 322 ++++++++++++++++++ ..._holdingsrecord_entity_type_definition.xml | 201 +++++++++++ 7 files changed, 654 insertions(+) create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/remove_items_instance_title_searchable.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/update_item_details_entity_type_definition.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml diff --git a/.gitignore b/.gitignore index 549e00a2..a8c95021 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ +.env ### STS ### .apt_generated diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index 731d2d0a..e74c9b4c 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -6,5 +6,6 @@ + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml b/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml new file mode 100644 index 00000000..0fb7103d --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml new file mode 100644 index 00000000..dc83d89b --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml @@ -0,0 +1,48 @@ + + + + + + + + + SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_inventory_item_status'; + + + + + SELECT src_inventory_item.id, + "left"(lower((instance_details.jsonb -> 'metadata'::text) ->> 'createdDate'::text), 600) AS instance_created_date, + hrim.instanceid AS instance_id, + jsonb_path_query_first(instance_details.jsonb, '$."contributors"[*]?(@."primary" == true)."name"'::jsonpath) #>> '{}'::text[] AS instance_primary_contributor, + instance_details.jsonb ->> 'title'::text AS instance_title, + "left"(lower((instance_details.jsonb -> 'metadata'::text) ->> 'updatedDate'::text), 600) AS instance_updated_date, + src_inventory_item.jsonb ->> 'barcode'::text AS item_barcode, + src_inventory_item.jsonb ->> 'copyNumber'::text AS item_copy_number, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'createdDate'::text AS item_created_date, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'prefix'::text AS item_effective_call_number_prefix, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'callNumber'::text AS item_effective_call_number_callnumber, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'suffix'::text AS item_effective_call_number_suffix, + src_inventory_item.jsonb ->> 'copyNumber'::text AS item_effective_call_number_copynumber, + concat_ws(', '::text, NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'prefix'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'callNumber'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'suffix'::text, ''::text), NULLIF(src_inventory_item.jsonb ->> 'copyNumber'::text, ''::text)) AS item_effective_call_number, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'typeId'::text AS item_effective_call_number_typeid, + src_inventory_item.effectivelocationid AS item_effective_location_id, + src_inventory_item.jsonb ->> 'hrid'::text AS item_hrid, + src_inventory_item.holdingsrecordid AS holdings_id, + src_inventory_item.jsonb ->> 'itemLevelCallNumber'::text AS item_level_call_number, + src_inventory_item.jsonb ->> 'itemLevelCallNumberTypeId'::text AS item_level_call_number_typeid, + src_inventory_item.materialtypeid AS item_material_type_id, + src_inventory_item.permanentlocationid AS item_permanent_location_id, + src_inventory_item.temporarylocationid AS item_temporary_location_id, + "left"(lower(${tenant_id}_mod_inventory_storage.f_unaccent((src_inventory_item.jsonb -> 'status'::text) ->> 'name'::text)), 600) AS item_status, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'updatedDate'::text AS item_updated_date + FROM src_inventory_item + JOIN src_inventory_holdings_record hrim ON src_inventory_item.holdingsrecordid = hrim.id + JOIN src_inventory_instance instance_details ON hrim.instanceid = instance_details.id; + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/remove_items_instance_title_searchable.xml b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_instance_title_searchable.xml new file mode 100644 index 00000000..a45b9a51 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_instance_title_searchable.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_inventory_item_status'; + + + + + SELECT src_inventory_item.id, + "left"(lower((instance_details.jsonb -> 'metadata'::text) ->> 'createdDate'::text), 600) AS instance_created_date, + hrim.instanceid AS instance_id, + jsonb_path_query_first(instance_details.jsonb, '$."contributors"[*]?(@."primary" == true)."name"'::jsonpath) #>> '{}'::text[] AS instance_primary_contributor, + instance_details.jsonb ->> 'title'::text AS instance_title, + "left"(lower((instance_details.jsonb -> 'metadata'::text) ->> 'updatedDate'::text), 600) AS instance_updated_date, + lower(src_inventory_item.jsonb ->> 'barcode'::text) AS item_barcode, + src_inventory_item.jsonb ->> 'copyNumber'::text AS item_copy_number, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'createdDate'::text AS item_created_date, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'prefix'::text AS item_effective_call_number_prefix, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'callNumber'::text AS item_effective_call_number_callnumber, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'suffix'::text AS item_effective_call_number_suffix, + src_inventory_item.jsonb ->> 'copyNumber'::text AS item_effective_call_number_copynumber, + concat_ws(', '::text, NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'prefix'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'callNumber'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'suffix'::text, ''::text), NULLIF(src_inventory_item.jsonb ->> 'copyNumber'::text, ''::text)) AS item_effective_call_number, + call_number_type_ref_data.jsonb ->> 'name'::text AS item_effective_call_number_type_name, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'typeId'::text AS item_effective_call_number_typeid, + loclib_ref_data.jsonb ->> 'code'::text AS item_effective_library_code, + loclib_ref_data.id AS item_effective_library_id, + loclib_ref_data.jsonb ->> 'name'::text AS item_effective_library_name, + src_inventory_item.effectivelocationid AS item_effective_location_id, + effective_location_ref_data.jsonb ->> 'name'::text AS item_effective_location_name, + src_inventory_item.jsonb ->> 'hrid'::text AS item_hrid, + src_inventory_item.holdingsrecordid AS holdings_id, + src_inventory_item.jsonb ->> 'itemLevelCallNumber'::text AS item_level_call_number, + call_item_number_type_ref_data.jsonb ->> 'name'::text AS item_level_call_number_type_name, + src_inventory_item.jsonb ->> 'itemLevelCallNumberTypeId'::text AS item_level_call_number_typeid, + material_type_ref_data.jsonb ->> 'name'::text AS item_material_type, + src_inventory_item.materialtypeid AS item_material_type_id, + src_inventory_item.permanentlocationid AS item_permanent_location_id, + permanent_location_ref_data.jsonb ->> 'name'::text AS item_permanent_location_name, + src_inventory_item.temporarylocationid AS item_temporary_location_id, + temporary_location_ref_data.jsonb ->> 'name'::text AS item_temporary_location_name, + "left"(lower(${tenant_id}_mod_inventory_storage.f_unaccent((src_inventory_item.jsonb -> 'status'::text) ->> 'name'::text)), 600) AS item_status, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'updatedDate'::text AS item_updated_date + FROM src_inventory_item + LEFT JOIN src_inventory_location effective_location_ref_data ON effective_location_ref_data.id = src_inventory_item.effectivelocationid + LEFT JOIN src_inventory_call_number_type call_number_type_ref_data ON call_number_type_ref_data.id::text = ((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'typeId'::text) + LEFT JOIN src_inventory_call_number_type call_item_number_type_ref_data ON call_item_number_type_ref_data.id::text = (src_inventory_item.jsonb ->> 'itemLevelCallNumberTypeId'::text) + LEFT JOIN src_inventory_loclibrary loclib_ref_data ON loclib_ref_data.id = effective_location_ref_data.libraryid + LEFT JOIN src_inventory_location permanent_location_ref_data ON permanent_location_ref_data.id = src_inventory_item.permanentlocationid + LEFT JOIN src_inventory_material_type material_type_ref_data ON material_type_ref_data.id = src_inventory_item.materialtypeid + LEFT JOIN src_inventory_location temporary_location_ref_data ON temporary_location_ref_data.id = src_inventory_item.temporarylocationid + JOIN src_inventory_holdings_record hrim ON src_inventory_item.holdingsrecordid = hrim.id + JOIN src_inventory_instance instance_details ON hrim.instanceid = instance_details.id; + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/update_item_details_entity_type_definition.xml b/src/main/resources/db/changelog/changes/v1.0.2/update_item_details_entity_type_definition.xml new file mode 100644 index 00000000..40a939f7 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/update_item_details_entity_type_definition.xml @@ -0,0 +1,322 @@ + + + + + { + "id": "0cb79a4c-f7eb-4941-a104-745224ae0292", + "name": "drv_item_details", + "labelAlias": "Items", + "subEntityTypeIds": [ + "097a6f96-edd0-11ed-a05b-0242ac120003", + "0cb79a4c-f7eb-4941-a104-745224ae0293" + ], + "private": false, + "columns": [ + { + "name": "holdings_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Holdings ID", + "visibleByDefault": false + }, + { + "name": "instance_created_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Instance created date", + "visibleByDefault": false + }, + { + "name": "instance_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Instance ID", + "visibleByDefault": false + }, + { + "name": "instance_primary_contributor", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Instance primary contributor", + "visibleByDefault": false + }, + { + "name": "instance_title", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Instance title", + "visibleByDefault": true + }, + { + "name": "instance_updated_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Instance updated date", + "visibleByDefault": false + }, + { + "name": "item_barcode", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item barcode", + "visibleByDefault": true + }, + { + "name": "item_level_call_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item call number", + "visibleByDefault": false + }, + { + "name": "item_level_call_number_type_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item call number type name", + "visibleByDefault": false, + "idColumnName": "item_level_call_number_typeid", + "source": { + "entityTypeId": "5c8315be-13f5-4df5-ae8b-086bae83484d", + "columnName": "call_number_type_name" + } + }, + { + "name": "item_level_call_number_typeid", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item call number type ID", + "visibleByDefault": false + }, + { + "name": "item_copy_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item copy number", + "visibleByDefault": true + }, + { + "name": "item_created_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Item created date", + "visibleByDefault": false + }, + { + "name": "item_effective_call_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective call number", + "visibleByDefault": true + }, + { + "name": "item_effective_call_number_type_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective call number type name", + "visibleByDefault": false, + "idColumnName": "item_effective_call_number_typeid", + "source": { + "entityTypeId": "5c8315be-13f5-4df5-ae8b-086bae83484d", + "columnName": "call_number_type_name" + } + }, + { + "name": "item_effective_call_number_typeid", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item effective call number type ID", + "visibleByDefault": false + }, + { + "name": "item_effective_library_code", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective library code", + "visibleByDefault": false + }, + { + "name": "item_effective_library_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item effective library ID", + "visibleByDefault": false + }, + { + "name": "item_effective_library_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective library name", + "visibleByDefault": false, + "idColumnName": "item_effective_library_id", + "source": { + "entityTypeId": "cf9f5c11-e943-483c-913b-81d1e338accc", + "columnName": "loclibrary_name" + } + }, + { + "name": "item_effective_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item effective location ID", + "visibleByDefault": false + }, + { + "name": "item_effective_location_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective location name", + "visibleByDefault": true, + "idColumnName": "item_effective_location_id", + "source": { + "entityTypeId": "a9d6305e-fdb4-4fc4-8a73-4a5f76d8410b", + "columnName": "location_name" + } + }, + { + "name": "item_hrid", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item hrid", + "visibleByDefault": false + }, + { + "name": "id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item ID", + "visibleByDefault": false + }, + { + "name": "item_material_type", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item material type", + "visibleByDefault": false, + "idColumnName": "item_material_type_id", + "source": { + "entityTypeId": "917ea5c8-cafe-4fa6-a942-e2388a88c6f6", + "columnName": "material_type_name" + } + }, + { + "name": "item_material_type_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item material ID", + "visibleByDefault": false + }, + { + "name": "item_permanent_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item permanent ID", + "visibleByDefault": false + }, + { + "name": "item_permanent_location_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item permanent location name", + "visibleByDefault": false, + "idColumnName": "item_permanent_location_id", + "source": { + "entityTypeId": "a9d6305e-fdb4-4fc4-8a73-4a5f76d8410b", + "columnName": "location_name" + } + }, + { + "name": "item_status", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item status", + "visibleByDefault": false, + "source": { + "entityTypeId": "a1a37288-1afe-4fa5-ab59-a5bcf5d8ca2d", + "columnName": "item_status" + } + }, + { + "name": "item_temporary_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item temporary ID", + "visibleByDefault": false + }, + { + "name": "item_temporary_location_name", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item temporary location name", + "visibleByDefault": false, + "idColumnName": "item_temporary_location_id", + "source": { + "entityTypeId": "a9d6305e-fdb4-4fc4-8a73-4a5f76d8410b", + "columnName": "location_name" + } + }, + { + "name": "item_updated_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Item updated date", + "visibleByDefault": false + } + ], + "defaultSort": [ + { + "columnName": "item_effective_location_name", + "direction": "ASC" + }, + { + "columnName": "instance_title", + "direction": "ASC" + }, + { + "columnName": "instance_primary_contributor", + "direction": "ASC" + }, + { + "columnName": "id", + "direction": "ASC" + } + ] + } + + id = '0cb79a4c-f7eb-4941-a104-745224ae0292' + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml b/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml new file mode 100644 index 00000000..138aa911 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml @@ -0,0 +1,201 @@ + + + + + { + "id": "0cb79a4c-f7eb-4941-a104-745224ae0293", + "name": "drv_item_holdingsrecord_instance", + "labelAlias": "Items, Holdings records, Instance", + "private": true, + "columns": [ + { + "name": "holdings_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Holdings ID", + "visibleByDefault": false + }, + { + "name": "instance_created_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Instance created date", + "visibleByDefault": false + }, + { + "name": "instance_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Instance ID", + "visibleByDefault": false + }, + { + "name": "instance_primary_contributor", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Instance primary contributor", + "visibleByDefault": false + }, + { + "name": "instance_title", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Instance title", + "visibleByDefault": true + }, + { + "name": "instance_title_searchable", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Instance title (Searchable)", + "visibleByDefault": true + }, + { + "name": "instance_updated_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Instance updated date", + "visibleByDefault": false + }, + { + "name": "item_barcode", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item barcode", + "visibleByDefault": true + }, + { + "name": "item_level_call_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item call number", + "visibleByDefault": false + }, + { + "name": "item_level_call_number_typeid", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item call number type ID", + "visibleByDefault": false + }, + { + "name": "item_copy_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item copy number", + "visibleByDefault": true + }, + { + "name": "item_created_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Item created date", + "visibleByDefault": false + }, + { + "name": "item_effective_call_number", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item effective call number", + "visibleByDefault": true + }, + { + "name": "item_effective_call_number_typeid", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item effective call number type ID", + "visibleByDefault": false + }, + { + "name": "item_effective_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item location ID", + "visibleByDefault": false + }, + { + "name": "item_hrid", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item hrid", + "visibleByDefault": false + }, + { + "name": "id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item ID", + "visibleByDefault": false + }, + { + "name": "item_material_type_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item material ID", + "visibleByDefault": false + }, + { + "name": "item_permanent_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item permanent ID", + "visibleByDefault": false + }, + { + "name": "item_status", + "dataType": { + "dataType": "stringType" + }, + "labelAlias": "Item status", + "visibleByDefault": false, + "source": { + "entityTypeId": "a1a37288-1afe-4fa5-ab59-a5bcf5d8ca2d", + "columnName": "item_status" + } + }, + { + "name": "item_temporary_location_id", + "dataType": { + "dataType": "rangedUUIDType" + }, + "labelAlias": "Item temporary ID", + "visibleByDefault": false + }, + { + "name": "item_updated_date", + "dataType": { + "dataType": "dateType" + }, + "labelAlias": "Item updated date", + "visibleByDefault": false + } + ] + } + + id = '0cb79a4c-f7eb-4941-a104-745224ae0293' + + + + From 5d10eac669ee18354989d6a620f6470e8efceca8 Mon Sep 17 00:00:00 2001 From: Noah Overcash Date: Fri, 3 Nov 2023 09:53:33 -0600 Subject: [PATCH 02/16] oops --- .../update_item_holdingsrecord_entity_type_definition.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml b/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml index 138aa911..958e1928 100644 --- a/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml +++ b/src/main/resources/db/changelog/changes/v1.0.2/update_item_holdingsrecord_entity_type_definition.xml @@ -51,14 +51,6 @@ "labelAlias": "Instance title", "visibleByDefault": true }, - { - "name": "instance_title_searchable", - "dataType": { - "dataType": "stringType" - }, - "labelAlias": "Instance title (Searchable)", - "visibleByDefault": true - }, { "name": "instance_updated_date", "dataType": { From 2cb6880e6460601a9b4daadac1e5ab3955d18317 Mon Sep 17 00:00:00 2001 From: Bobby Sharp Date: Fri, 3 Nov 2023 12:23:56 -0400 Subject: [PATCH 03/16] Fix view name --- .../remove_items_holdingsrecord_instance_title_searchable.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml index dc83d89b..61dd64b8 100644 --- a/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml +++ b/src/main/resources/db/changelog/changes/v1.0.2/remove_items_holdingsrecord_instance_title_searchable.xml @@ -12,7 +12,7 @@ SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_inventory_item_status'; - + SELECT src_inventory_item.id, "left"(lower((instance_details.jsonb -> 'metadata'::text) ->> 'createdDate'::text), 600) AS instance_created_date, From ada02716bb3564b424090bd339690dcc2448be41 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Fri, 3 Nov 2023 14:04:59 -0400 Subject: [PATCH 04/16] MODFQMMGR-73 Purge old queries using the start date This commit modifies the query purge process, to make it use the query start date instead of the end date. If the server shuts down while a query is still running, the end date doesn't get set, so those queries weren't getting purged. Using the start date avoids that issue. This means that queries may get purged a little sooner (e.g., if a query takes 20 minutes to run, we'd potentially purge it 20 minutes sooner), but the threshold is long enough (3 hours and can be overridden at runtime) that this should be okay --- .../folio/fqm/repository/QueryRepository.java | 4 ++-- .../fqm/service/QueryManagementService.java | 2 +- .../fqm/repository/QueryRepositoryTest.java | 23 ++++++++++++++----- .../service/QueryManagementServiceTest.java | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/folio/fqm/repository/QueryRepository.java b/src/main/java/org/folio/fqm/repository/QueryRepository.java index 73c27312..d04a3e13 100644 --- a/src/main/java/org/folio/fqm/repository/QueryRepository.java +++ b/src/main/java/org/folio/fqm/repository/QueryRepository.java @@ -73,10 +73,10 @@ public Optional getQuery(UUID queryId, boolean useCache) { .fetchOneInto(Query.class)); } - public List getQueryIdsCompletedBefore(Duration duration) { + public List getQueryIdsStartedBefore(Duration duration) { return jooqContext.select(field(QUERY_ID)) .from(table(QUERY_DETAILS_TABLE)) - .where(field("end_date"). + .where(field("start_date"). lessOrEqual(OffsetDateTime.now().minus(duration))) .fetchInto(UUID.class); } diff --git a/src/main/java/org/folio/fqm/service/QueryManagementService.java b/src/main/java/org/folio/fqm/service/QueryManagementService.java index f6d3f4e1..925b65b0 100644 --- a/src/main/java/org/folio/fqm/service/QueryManagementService.java +++ b/src/main/java/org/folio/fqm/service/QueryManagementService.java @@ -133,7 +133,7 @@ public Optional getQuery(UUID queryId, boolean includeResults, int */ @Transactional public PurgedQueries deleteOldQueries() { - List queryIds = queryRepository.getQueryIdsCompletedBefore(queryRetentionDuration); + List queryIds = queryRepository.getQueryIdsStartedBefore(queryRetentionDuration); log.info("Deleting the queries with queryIds {}", queryIds); deleteQueryAndResults(queryIds); return new PurgedQueries().deletedQueryIds(queryIds); diff --git a/src/test/java/org/folio/fqm/repository/QueryRepositoryTest.java b/src/test/java/org/folio/fqm/repository/QueryRepositoryTest.java index bce45bdf..f1b60bfc 100644 --- a/src/test/java/org/folio/fqm/repository/QueryRepositoryTest.java +++ b/src/test/java/org/folio/fqm/repository/QueryRepositoryTest.java @@ -12,9 +12,9 @@ import java.time.Duration; import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; import java.util.UUID; -import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; import static org.springframework.util.StringUtils.hasText; @@ -86,15 +86,26 @@ void shouldGetQueriesForDeletion() throws InterruptedException { {"field1": {"$in": ["value1", "value2", "value3", "value4", "value5" ] }} """; List fields = List.of("id", "field1"); - Query query = new Query(queryId, UUID.randomUUID(), fqlQuery, fields, + Query queryToDelete = new Query(queryId, UUID.randomUUID(), fqlQuery, fields, UUID.randomUUID(), OffsetDateTime.now(), null, QueryStatus.IN_PROGRESS, null); - repo.saveQuery(query); + repo.saveQuery(queryToDelete); Query updatedQuery = new Query(queryId, UUID.randomUUID(), fqlQuery, fields, UUID.randomUUID(), null, OffsetDateTime.now(), QueryStatus.SUCCESS, null); + + UUID queryId2 = UUID.randomUUID(); + Query queryToNotDelete = new Query(queryId2, UUID.randomUUID(), fqlQuery, fields, + UUID.randomUUID(), OffsetDateTime.now().plusHours(1), null, QueryStatus.IN_PROGRESS, null); + repo.saveQuery(queryToNotDelete); + repo.updateQuery(updatedQuery.queryId(), updatedQuery.status(), updatedQuery.endDate(), updatedQuery.failureReason()); - List expectedIds = List.of(queryId); - List actualIds = repo.getQueryIdsCompletedBefore(Duration.ofMillis(0)); - assertEquals(expectedIds, actualIds); + UUID expectedId = queryId; + List actualIds = repo.getQueryIdsStartedBefore(Duration.ofMillis(0)); + + assertTrue(actualIds.contains(expectedId)); + assertFalse(actualIds.contains(queryId2)); + + // Clean up + repo.deleteQueries(List.of(queryId2)); } @Test diff --git a/src/test/java/org/folio/fqm/service/QueryManagementServiceTest.java b/src/test/java/org/folio/fqm/service/QueryManagementServiceTest.java index 36b3d4bd..3885c91d 100644 --- a/src/test/java/org/folio/fqm/service/QueryManagementServiceTest.java +++ b/src/test/java/org/folio/fqm/service/QueryManagementServiceTest.java @@ -381,7 +381,7 @@ void validateQueryShouldThrowErrorForInvalidFql() { void shouldPurgeQueries() { List queryIds = List.of(UUID.randomUUID(), UUID.randomUUID()); PurgedQueries expectedPurgedQueries = new PurgedQueries().deletedQueryIds(queryIds); - when(queryRepository.getQueryIdsCompletedBefore(Mockito.any())).thenReturn(queryIds); + when(queryRepository.getQueryIdsStartedBefore(Mockito.any())).thenReturn(queryIds); PurgedQueries actualPurgedQueries = queryManagementService.deleteOldQueries(); verify(queryResultsRepository, times(1)).deleteQueryResults(queryIds); verify(queryRepository, times(1)).deleteQueries(queryIds); From 4e569ff5d0d041794a5d70902d04cbc67f6a2fe1 Mon Sep 17 00:00:00 2001 From: Kriti Jain Date: Mon, 6 Nov 2023 11:33:22 -0500 Subject: [PATCH 05/16] User preferred contact type is incorrect in the records table --- .../changes/v1.0.2/changelog-v1.0.2.xml | 3 + ...ix_user_details_preferred_contact_type.xml | 98 ++++++++ ...te_user_details_entity_type_definition.xml | 224 ++++++++++++++++++ 3 files changed, 325 insertions(+) create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/fix_user_details_preferred_contact_type.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.2/update_user_details_entity_type_definition.xml diff --git a/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml b/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml index 0fb7103d..838e3368 100644 --- a/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml +++ b/src/main/resources/db/changelog/changes/v1.0.2/changelog-v1.0.2.xml @@ -10,4 +10,7 @@ + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/fix_user_details_preferred_contact_type.xml b/src/main/resources/db/changelog/changes/v1.0.2/fix_user_details_preferred_contact_type.xml new file mode 100644 index 00000000..3c0edd39 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/fix_user_details_preferred_contact_type.xml @@ -0,0 +1,98 @@ + + + + + + + + + SELECT + userDetails.jsonb -> 'personal' ->> 'firstName' as user_first_name, + userDetails.jsonb -> 'personal' ->> 'lastName' as user_last_name, + userDetails.jsonb ->>'barcode' as user_barcode, + userDetails.jsonb ->>'username' as username, + userDetails.id as id, + userDetails.jsonb ->> 'externalSystemId' as user_external_system_id, + userDetails.jsonb ->> 'active' as user_active, + userDetails.jsonb -> 'personal' ->> 'email' as user_email, + userDetails.jsonb -> 'metadata' ->> 'createdDate' as user_created_date, + userDetails.jsonb -> 'metadata' ->> 'updatedDate' as user_updated_date, + userDetails.jsonb -> 'personal' ->> 'preferredFirstName' as user_preferred_first_name, + userDetails.jsonb -> 'personal' ->> 'middleName' as user_middle_name, + userDetails.jsonb -> 'personal' ->> 'phone' as user_phone, + userDetails.jsonb -> 'personal' ->> 'mobilePhone' as user_mobile_phone, + userDetails.jsonb -> 'personal' ->> 'dateOfBirth' as user_date_of_birth, + userDetails.jsonb ->> 'expirationDate'::text AS user_expiration_date, + userDetails.jsonb ->> 'enrollmentDate'::text AS user_enrollment_date, + patron_id_ref_data.jsonb ->> 'group'::text AS user_patron_group, + patron_id_ref_data.id::text AS user_patron_group_id, + UserDetails.jsonb -> 'personal' ->> 'preferredContactTypeId' as user_preferred_contact_type_id, + CASE UserDetails.jsonb -> 'personal' ->> 'preferredContactTypeId' + WHEN '001' THEN 'Mail (Primary Address)' + WHEN '002' THEN 'Email' + WHEN '003' THEN 'Text Message' + ELSE 'unknown' + END AS user_preferred_contact_type, + concat_ws(', '::text, + NULLIF(( SELECT subquery.addressline1 + FROM ( SELECT add_id.value ->> 'addressLine1'::text AS addressline1, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text), + NULLIF(( SELECT subquery.addressline2 + FROM ( SELECT add_id.value ->> 'addressLine2'::text AS addressline2, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text), + NULLIF(( SELECT subquery.city + FROM ( SELECT add_id.value ->> 'city'::text AS city, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text), + NULLIF(( SELECT subquery.region + FROM ( SELECT add_id.value ->> 'region'::text AS region, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text), + NULLIF(( SELECT subquery.postalcode + FROM ( SELECT add_id.value ->> 'postalCode'::text AS postalcode, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text), + NULLIF(( SELECT subquery.countryid + FROM ( SELECT add_id.value ->> 'countryId'::text AS countryid, + row_number() OVER (ORDER BY (add_id.value ->> 'primaryAddress'::text)) AS row_num + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) subquery + WHERE subquery.row_num = 1), ''::text)) AS user_primary_address, + ( SELECT array_agg(add_id.value ->> 'city'::text) FILTER (WHERE (add_id.value ->> 'city'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS cities, + ( SELECT array_agg(add_id.value ->> 'region'::text) FILTER (WHERE (add_id.value ->> 'region'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS regions, + ( SELECT array_agg(add_id.value ->> 'countryId'::text) FILTER (WHERE (add_id.value ->> 'countryId'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS country_ids, + ( SELECT array_agg(add_id.value ->> 'postalCode'::text) FILTER (WHERE (add_id.value ->> 'postalCode'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS postal_codes, + ( SELECT array_agg(add_id.value ->> 'addressLine1'::text) FILTER (WHERE (add_id.value ->> 'addressLine1'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS address_line1, + ( SELECT array_agg(add_id.value ->> 'addressLine2'::text) FILTER (WHERE (add_id.value ->> 'addressLine2'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS address_line2, + ( SELECT array_agg(add_id.value ->> 'addressTypeId'::text) FILTER (WHERE (add_id.value ->> 'addressTypeId'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value)) AS address_ids, + ( SELECT array_agg(a.jsonb ->> 'addressType'::text) FILTER (WHERE (a.jsonb ->> 'addressType'::text) IS NOT NULL) AS array_agg + FROM jsonb_array_elements((userdetails.jsonb -> 'personal'::text) -> 'addresses'::text) add_id(value) + JOIN src_users_addresstype a ON (add_id.value ->> 'addressTypeId'::text) = a.id::text) AS address_type_names, + array_agg(temp_departments.id::text) FILTER (where temp_departments.id is not null) as department_ids, + array_agg(temp_departments.jsonb ->> 'name') FILTER (where temp_departments.jsonb ->> 'name' is not null) as department_names + FROM src_users_users userdetails + LEFT JOIN src_users_groups patron_id_ref_data ON patron_id_ref_data.id = ((userdetails.jsonb ->> 'patronGroup'::text)::uuid) + LEFT JOIN src_users_departments as temp_departments ON userdetails.jsonb -> 'departments' ?? temp_departments.id::text + GROUP BY userdetails.id, userdetails.jsonb, patron_id_ref_data.id, patron_id_ref_data.jsonb + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.2/update_user_details_entity_type_definition.xml b/src/main/resources/db/changelog/changes/v1.0.2/update_user_details_entity_type_definition.xml new file mode 100644 index 00000000..1b26988d --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.2/update_user_details_entity_type_definition.xml @@ -0,0 +1,224 @@ + + + + + { + "id": "0069cf6f-2833-46db-8a51-8934769b8289", + "name":"drv_user_details", + "labelAlias" : "Users", + "private" : false, + "columns": [ + { + "name": "user_active", + "dataType":{ + "dataType":"booleanType" + }, + "labelAlias": "User active", + "visibleByDefault": true, + "values": [ + { + "value": "true", + "label": "True" + }, + { + "value": "false", + "label": "False" + } + ] + }, + { + "name": "user_barcode", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User barcode", + "visibleByDefault": true + }, + { + "name": "user_created_date", + "dataType":{ + "dataType":"dateType" + }, + "labelAlias": "User created date", + "visibleByDefault": false + }, + { + "name": "user_date_of_birth", + "dataType":{ + "dataType":"dateType" + }, + "labelAlias": "User date of birth", + "visibleByDefault": false + }, + { + "name": "user_email", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User email", + "visibleByDefault": false + }, + { + "name": "user_enrollment_date", + "dataType":{ + "dataType":"dateType" + }, + "labelAlias": "User enrollment date", + "visibleByDefault": false + }, + { + "name": "user_expiration_date", + "dataType":{ + "dataType":"dateType" + }, + "labelAlias": "User expiration date", + "visibleByDefault": false + }, + { + "name": "user_external_system_id", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User external system ID", + "visibleByDefault": false + }, + { + "name": "user_first_name", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User first name", + "visibleByDefault": true + }, + { + "name": "id", + "dataType":{ + "dataType":"rangedUUIDType" + }, + "labelAlias": "User ID", + "visibleByDefault": true + }, + { + "name": "user_last_name", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User last name", + "visibleByDefault": true + }, + { + "name": "user_middle_name", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User middle name", + "visibleByDefault": false + }, + { + "name": "user_mobile_phone", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User mobile phone", + "visibleByDefault": false + }, + { + "name": "user_patron_group", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User patron group", + "visibleByDefault": false, + "idColumnName": "user_patron_group_id", + "source": { + "entityTypeId": "e611264d-377e-4d87-a93f-f1ca327d3db0", + "columnName": "group" + } + }, + { + "name": "user_patron_group_id", + "dataType":{ + "dataType":"rangedUUIDType" + }, + "labelAlias": "User patron group ID", + "visibleByDefault": false + }, + { + "name": "user_phone", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User phone", + "visibleByDefault": true + }, + { + "name": "user_preferred_contact_type", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User preferred contact type", + "visibleByDefault": false, + "values": [ + { + "value": "Email", + "label": "Email" + }, + { + "value": "Mail (Primary Address)", + "label": "Mail (Primary Address)" + }, + { + "value": "Text Message", + "label": "Text Message" + } + ] + }, + { + "name": "user_preferred_first_name", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User preferred first name", + "visibleByDefault": true + }, + { + "name": "user_primary_address", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "User primary address", + "visibleByDefault": false + }, + { + "name": "user_updated_date", + "dataType":{ + "dataType":"dateType" + }, + "labelAlias": "User updated date", + "visibleByDefault": false + }, + { + "name": "username", + "dataType":{ + "dataType":"stringType" + }, + "labelAlias": "Username", + "visibleByDefault": true + } + ], + "defaultSort": [ + { + "columnName": "id", + "direction": "ASC" + } + ] + } + + id = '0069cf6f-2833-46db-8a51-8934769b8289' + + + + From ada763970cf298043705ed10d5c98ebc4ab2843e Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Mon, 6 Nov 2023 14:02:17 -0500 Subject: [PATCH 06/16] MODFQMMGR-77 Update the provided tenant API in MD This commit makes mod-fqm-manager provide the _tenant 2.0 interface, which will make Okapi use the POST /_/tenant API for all tenant actions --- descriptors/ModuleDescriptor-template.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index c6d18b4e..eb27c3d2 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -4,15 +4,18 @@ "provides": [ { "id": "_tenant", - "version": "1.2", + "version": "2.0", "interfaceType": "system", "handlers": [ { "methods": ["POST"], - "pathPattern": "/_/tenant" - }, { - "methods": ["DELETE"], - "pathPattern": "/_/tenant" + "pathPattern": "/_/tenant", + "permissionsRequired": [] + }, + { + "methods": ["GET", "DELETE"], + "pathPattern": "/_/tenant/{id}", + "permissionsRequired": [] } ] }, From ada0d99e824327079878ae5ce329b9be7db60338 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Tue, 7 Nov 2023 11:46:48 -0500 Subject: [PATCH 07/16] Update NEWS --- NEWS.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3e13bb31..59974aeb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,10 @@ -# 1.0.0 -- Initial release +# 1.0.x + +## 1.0.2 +- Remove the instance_titel_searchable field from the Items entity type +- Purge old query results based on query start date/time instead of the end date/time +- Fix bug in user preferred contact type +- Update the provided `_tenant` interface in the module descriptor to 2.0 ## 1.0.1 - [MODFQMMGR-57](https://issues.folio.org/browse/MODFQMMGR-57) Use a different version of f_unaccent(), to allow us to make use of an index @@ -8,3 +13,6 @@ - [MODFQMMGR-67](https://issues.folio.org/browse/MODFQMMGR-67) Enable batched inserts - [MODFQMMGR-71](https://issues.folio.org/browse/MODFQMMGR-71) Update item and user entity types - [MODFQMMGR-31](https://issues.folio.org/browse/MODFQMMGR-31) Fix Users dropdown + +## 1.0.0 +- Initial release From adab74f80dc18718ba66f5c75183396bf4133547 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Tue, 7 Nov 2023 11:47:27 -0500 Subject: [PATCH 08/16] Point scm settings in POM to the community repo --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index dbaa8d85..9becd0fe 100644 --- a/pom.xml +++ b/pom.xml @@ -373,10 +373,10 @@ - https://github.com/EBSCOIS/${project.artifactId} - scm:git:git://github.com/EBSCOIS/${project.artifactId}.git - scm:git:git@github.com:EBSCOIS/${project.artifactId}.git - v1.0.0 + https://github.com/folio-org/${artifactId} + scm:git:git://github.com/folio-org/${artifactId}.git + scm:git:git@github.com:folio-org/${artifactId}.git + HEAD From 891cda538fea23933cc3e38a986a57d4d80b18e9 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Tue, 7 Nov 2023 11:59:16 -0500 Subject: [PATCH 09/16] [maven-release-plugin] prepare release v1.0.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9becd0fe..ec6fa9e4 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.folio mod-fqm-manager mod-fqm-manager - 1.0.2-SNAPSHOT + 1.0.2 FOLIO Query Machine manager jar @@ -376,7 +376,7 @@ https://github.com/folio-org/${artifactId} scm:git:git://github.com/folio-org/${artifactId}.git scm:git:git@github.com:folio-org/${artifactId}.git - HEAD + v1.0.2 From adae207cb24943b68bbfaf9b314768c7a3980b7d Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Tue, 7 Nov 2023 11:59:16 -0500 Subject: [PATCH 10/16] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ec6fa9e4..0a190739 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.folio mod-fqm-manager mod-fqm-manager - 1.0.2 + 1.0.3-SNAPSHOT FOLIO Query Machine manager jar @@ -376,7 +376,7 @@ https://github.com/folio-org/${artifactId} scm:git:git://github.com/folio-org/${artifactId}.git scm:git:git@github.com:folio-org/${artifactId}.git - v1.0.2 + HEAD From 452c490b8f31cc6c811e8be5f5c0bcc8acaeb279 Mon Sep 17 00:00:00 2001 From: Kriti Jain Date: Tue, 7 Nov 2023 13:43:04 -0500 Subject: [PATCH 11/16] refactor drv item call number view --- .../db/changelog/changelog-master.xml | 1 + .../changes/v1.0.3/changelog-v1.0.3.xml | 8 +++ .../refactor drv_item_callnumber_location.xml | 53 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml create mode 100644 src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index e74c9b4c..3389bd25 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -7,5 +7,6 @@ + diff --git a/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml b/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml new file mode 100644 index 00000000..9de85dd3 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml b/src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml new file mode 100644 index 00000000..ad326b43 --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml @@ -0,0 +1,53 @@ + + + + + + + + + + SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_inventory_item_status'; + + + + + SELECT + src_inventory_item.id, + src_inventory_item.holdingsrecordid AS item_holdings_record_id, + src_inventory_item.jsonb ->> 'hrid'::text AS item_hrid, + src_inventory_item.jsonb ->> 'itemLevelCallNumber'::text AS item_level_call_number, + src_inventory_item.jsonb ->> 'itemLevelCallNumberTypeId'::text AS item_level_call_number_typeid, + call_item_number_type_ref_data.jsonb ->> 'name'::text AS item_level_call_number_type_name, + concat_ws(', '::text, NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'prefix'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'callNumber'::text, ''::text), NULLIF((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'suffix'::text, ''::text), NULLIF(src_inventory_item.jsonb ->> 'copyNumber'::text, ''::text)) AS item_effective_call_number, + (src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'typeId'::text AS item_effective_call_number_typeid, + call_number_type_ref_data.jsonb ->> 'name'::text AS item_effective_call_number_type_name, + loclib_ref_data.id AS item_effective_library_id, + loclib_ref_data.jsonb ->> 'name'::text AS item_effective_library_name, + loclib_ref_data.jsonb ->> 'code'::text AS item_effective_library_code, + "left"(lower(${tenant_id}_mod_inventory_storage.f_unaccent((src_inventory_item.jsonb -> 'status'::text) ->> 'name'::text)), 600) AS item_status, + src_inventory_item.jsonb ->> 'copyNumber'::text AS item_copy_number, + src_inventory_item.jsonb ->> 'barcode'::text AS item_barcode, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'createdDate'::text AS item_created_date, + (src_inventory_item.jsonb -> 'metadata'::text) ->> 'updatedDate'::text AS item_updated_date, + effective_location_ref_data.id AS item_effective_location_id, + effective_location_ref_data.jsonb ->> 'name'::text AS item_effective_location_name, + permanent_location_ref_data.id AS item_permanent_location_id, + permanent_location_ref_data.jsonb ->> 'name'::text AS item_permanent_location_name, + material_type_ref_data.id AS item_material_type_id, + material_type_ref_data.jsonb ->> 'name'::text AS item_material_type + FROM src_inventory_item + LEFT JOIN src_inventory_location effective_location_ref_data ON effective_location_ref_data.id = src_inventory_item.effectivelocationid + LEFT JOIN src_inventory_call_number_type call_number_type_ref_data ON call_number_type_ref_data.id::text = ((src_inventory_item.jsonb -> 'effectiveCallNumberComponents'::text) ->> 'typeId'::text) + LEFT JOIN src_inventory_call_number_type call_item_number_type_ref_data ON call_item_number_type_ref_data.id::text = (src_inventory_item.jsonb ->> 'itemLevelCallNumberTypeId'::text) + LEFT JOIN src_inventory_loclibrary loclib_ref_data ON loclib_ref_data.id = effective_location_ref_data.libraryid + LEFT JOIN src_inventory_location permanent_location_ref_data ON permanent_location_ref_data.id = src_inventory_item.permanentlocationid + LEFT JOIN src_inventory_material_type material_type_ref_data ON material_type_ref_data.id = src_inventory_item.materialtypeid; + + + + From 19db29759f85a1167720c89f7c119a03d9bc339d Mon Sep 17 00:00:00 2001 From: Bobby Sharp Date: Tue, 7 Nov 2023 08:48:25 -0500 Subject: [PATCH 12/16] MODFQMMGR-76: Periodically refresh materialized views --- descriptors/ModuleDescriptor-template.json | 21 ++++++++- .../MaterializedViewRefreshRepository.java | 30 +++++++++++++ .../MaterializedViewRefreshController.java | 21 +++++++++ .../MaterializedViewRefreshService.java | 15 +++++++ .../v1.0.3/add_materialized_view_indexes.xml | 22 ++++++++++ .../changes/v1.0.3/changelog-v1.0.3.xml | 3 +- ...refactor_drv_item_callnumber_location.xml} | 0 .../swagger.api/mod-fqm-manager.yaml | 13 ++++++ ...MaterializedViewRefreshControllerTest.java | 43 +++++++++++++++++++ ...MaterializedViewRefreshRepositoryTest.java | 29 +++++++++++++ .../MaterializedViewRefreshServiceTest.java | 28 ++++++++++++ 11 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/folio/fqm/repository/MaterializedViewRefreshRepository.java create mode 100644 src/main/java/org/folio/fqm/resource/MaterializedViewRefreshController.java create mode 100644 src/main/java/org/folio/fqm/service/MaterializedViewRefreshService.java create mode 100644 src/main/resources/db/changelog/changes/v1.0.3/add_materialized_view_indexes.xml rename src/main/resources/db/changelog/changes/v1.0.3/{sql/refactor drv_item_callnumber_location.xml => refactor_drv_item_callnumber_location.xml} (100%) create mode 100644 src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java create mode 100644 src/test/java/org/folio/fqm/repository/MaterializedViewRefreshRepositoryTest.java create mode 100644 src/test/java/org/folio/fqm/service/MaterializedViewRefreshServiceTest.java diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index eb27c3d2..f50c5528 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -1,6 +1,6 @@ { "id": "@artifactId@-@version@", - "name": "The module descriptor for mod-fqm-manager.", + "name": "FQM Manager Module", "provides": [ { "id": "_tenant", @@ -78,6 +78,11 @@ "methods": ["DELETE"], "pathPattern": "/query/{query-id}", "permissionsRequired": ["fqm.query.async.delete"] + }, + { + "methods": ["POST"], + "pathPattern": "/materialized-views/refresh", + "permissionsRequired": ["fqm.materializedViews.post"] } ] }, @@ -87,10 +92,16 @@ "interfaceType": "system", "handlers": [ { - "methods": [ "POST" ], + "methods": ["POST"], "pathPattern": "/query/purge", "unit": "hour", "delay": "1" + }, + { + "methods": ["POST"], + "pathPattern": "/materialized-views/refresh", + "unit": "hour", + "delay": "24" } ] } @@ -144,6 +155,12 @@ "description": "Run a query synchronously and get results", "visible": true }, + { + "permissionName": "fqm.materializedViews.post", + "displayName": "FQM - Refresh materialized views", + "description": "Refresh FQM materialized views", + "visible": true + }, { "permissionName": "fqm.query.all", "displayName": "FQM - All permissions", diff --git a/src/main/java/org/folio/fqm/repository/MaterializedViewRefreshRepository.java b/src/main/java/org/folio/fqm/repository/MaterializedViewRefreshRepository.java new file mode 100644 index 00000000..e45d9f83 --- /dev/null +++ b/src/main/java/org/folio/fqm/repository/MaterializedViewRefreshRepository.java @@ -0,0 +1,30 @@ +package org.folio.fqm.repository; + +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; +import org.jooq.DSLContext; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +@RequiredArgsConstructor +@Log4j2 +public class MaterializedViewRefreshRepository { + private static final String REFRESH_MATERIALIZED_VIEW_SQL = "REFRESH MATERIALIZED VIEW CONCURRENTLY "; + + private static final List materializedViewNames = List.of( + "drv_circulation_loan_status", + "drv_inventory_item_status" + ); + + private final DSLContext jooqContext; + + public void refreshMaterializedViews(String tenantId) { + for (String matViewName : materializedViewNames) { + String fullName = tenantId + "_mod_fqm_manager." + matViewName; + log.info("Refreshing materialized view {}", fullName); + jooqContext.execute(REFRESH_MATERIALIZED_VIEW_SQL + fullName); + } + } +} diff --git a/src/main/java/org/folio/fqm/resource/MaterializedViewRefreshController.java b/src/main/java/org/folio/fqm/resource/MaterializedViewRefreshController.java new file mode 100644 index 00000000..7da2c3cb --- /dev/null +++ b/src/main/java/org/folio/fqm/resource/MaterializedViewRefreshController.java @@ -0,0 +1,21 @@ +package org.folio.fqm.resource; + +import lombok.RequiredArgsConstructor; +import org.folio.fqm.service.MaterializedViewRefreshService; +import org.folio.spring.FolioExecutionContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class MaterializedViewRefreshController implements MaterializedViewsApi { + private final FolioExecutionContext executionContext; + private final MaterializedViewRefreshService materializedViewRefreshService; + + @Override + public ResponseEntity refreshMaterializedViews() { + materializedViewRefreshService.refreshMaterializedViews(executionContext.getTenantId()); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} diff --git a/src/main/java/org/folio/fqm/service/MaterializedViewRefreshService.java b/src/main/java/org/folio/fqm/service/MaterializedViewRefreshService.java new file mode 100644 index 00000000..a7d1e00f --- /dev/null +++ b/src/main/java/org/folio/fqm/service/MaterializedViewRefreshService.java @@ -0,0 +1,15 @@ +package org.folio.fqm.service; + +import lombok.RequiredArgsConstructor; +import org.folio.fqm.repository.MaterializedViewRefreshRepository; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MaterializedViewRefreshService { + private final MaterializedViewRefreshRepository materializedViewRefreshRepository; + + public void refreshMaterializedViews(String tenantId) { + materializedViewRefreshRepository.refreshMaterializedViews(tenantId); + } +} diff --git a/src/main/resources/db/changelog/changes/v1.0.3/add_materialized_view_indexes.xml b/src/main/resources/db/changelog/changes/v1.0.3/add_materialized_view_indexes.xml new file mode 100644 index 00000000..d9b5eaec --- /dev/null +++ b/src/main/resources/db/changelog/changes/v1.0.3/add_materialized_view_indexes.xml @@ -0,0 +1,22 @@ + + + + + + SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_inventory_item_status'; + + + SELECT COUNT(*) FROM pg_matviews WHERE schemaname = '${tenant_id}_mod_fqm_manager'AND matviewname = 'drv_circulation_loan_status'; + + + + + + + + + + diff --git a/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml b/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml index 9de85dd3..52ca9bd9 100644 --- a/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml +++ b/src/main/resources/db/changelog/changes/v1.0.3/changelog-v1.0.3.xml @@ -4,5 +4,6 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"> - + + diff --git a/src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml b/src/main/resources/db/changelog/changes/v1.0.3/refactor_drv_item_callnumber_location.xml similarity index 100% rename from src/main/resources/db/changelog/changes/v1.0.3/sql/refactor drv_item_callnumber_location.xml rename to src/main/resources/db/changelog/changes/v1.0.3/refactor_drv_item_callnumber_location.xml diff --git a/src/main/resources/swagger.api/mod-fqm-manager.yaml b/src/main/resources/swagger.api/mod-fqm-manager.yaml index 789f6019..51a3c965 100644 --- a/src/main/resources/swagger.api/mod-fqm-manager.yaml +++ b/src/main/resources/swagger.api/mod-fqm-manager.yaml @@ -44,6 +44,19 @@ paths: $ref: '#/components/responses/badRequestResponse' '500': $ref: '#/components/responses/internalServerErrorResponse' + /materialized-views/refresh: + post: + operationId: refreshMaterializedViews + tags: + - materializedViews + description: Refresh all materialized views for a tenant. + responses: + '204': + description: 'Views refreshed' + '400': + $ref: '#/components/responses/badRequestResponse' + '500': + $ref: '#/components/responses/internalServerErrorResponse' components: diff --git a/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java b/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java new file mode 100644 index 00000000..baff8f67 --- /dev/null +++ b/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java @@ -0,0 +1,43 @@ +package org.folio.fqm.controller; + +import org.folio.fqm.resource.MaterializedViewRefreshController; +import org.folio.fqm.service.MaterializedViewRefreshService; +import org.folio.spring.FolioExecutionContext; +import org.folio.spring.integration.XOkapiHeaders; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.RequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(MaterializedViewRefreshController.class) +class MaterializedViewRefreshControllerTest { + @Autowired + private MockMvc mockMvc; + @MockBean + private FolioExecutionContext executionContext; + @MockBean + private MaterializedViewRefreshService materializedViewRefreshService; + + @Test + void refreshMaterializedViewsTest() throws Exception { + String tenantId = "tenant_01"; + RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/materialized-views/refresh") + .header(XOkapiHeaders.TENANT, tenantId) + .contentType(APPLICATION_JSON); + when(executionContext.getTenantId()).thenReturn(tenantId); + doNothing().when(materializedViewRefreshService).refreshMaterializedViews(tenantId); + mockMvc.perform(requestBuilder) + .andExpect(status().isNoContent()); + verify(materializedViewRefreshService, times(1)).refreshMaterializedViews(tenantId); + } +} diff --git a/src/test/java/org/folio/fqm/repository/MaterializedViewRefreshRepositoryTest.java b/src/test/java/org/folio/fqm/repository/MaterializedViewRefreshRepositoryTest.java new file mode 100644 index 00000000..565b963c --- /dev/null +++ b/src/test/java/org/folio/fqm/repository/MaterializedViewRefreshRepositoryTest.java @@ -0,0 +1,29 @@ +package org.folio.fqm.repository; + +import org.jooq.DSLContext; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class MaterializedViewRefreshRepositoryTest { + @InjectMocks + private MaterializedViewRefreshRepository materializedViewRefreshRepository; + @Mock + private DSLContext jooqContext; + + @Test + void refreshMaterializedViewsTest() { + String tenantId = "tenant_01"; + String expectedItemStatusSql = "REFRESH MATERIALIZED VIEW CONCURRENTLY tenant_01_mod_fqm_manager.drv_inventory_item_status"; + String expectedLoanStatusSql = "REFRESH MATERIALIZED VIEW CONCURRENTLY tenant_01_mod_fqm_manager.drv_circulation_loan_status"; + when(jooqContext.execute(anyString())).thenReturn(1); + materializedViewRefreshRepository.refreshMaterializedViews(tenantId); + verify(jooqContext, times(1)).execute(expectedItemStatusSql); + verify(jooqContext, times(1)).execute(expectedLoanStatusSql); + } +} diff --git a/src/test/java/org/folio/fqm/service/MaterializedViewRefreshServiceTest.java b/src/test/java/org/folio/fqm/service/MaterializedViewRefreshServiceTest.java new file mode 100644 index 00000000..70afa579 --- /dev/null +++ b/src/test/java/org/folio/fqm/service/MaterializedViewRefreshServiceTest.java @@ -0,0 +1,28 @@ +package org.folio.fqm.service; + +import org.folio.fqm.repository.MaterializedViewRefreshRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class MaterializedViewRefreshServiceTest { + @InjectMocks + private MaterializedViewRefreshService materializedViewRefreshService; + @Mock + private MaterializedViewRefreshRepository materializedViewRefreshRepository; + + @Test + void refreshMaterializedViewsTest() { + String tenantId = "tenant_01"; + doNothing().when(materializedViewRefreshRepository).refreshMaterializedViews(tenantId); + materializedViewRefreshService.refreshMaterializedViews(tenantId); + verify(materializedViewRefreshRepository, times(1)).refreshMaterializedViews(tenantId); + } +} From 24ce61a4084372c484776dd36f972969323ebd93 Mon Sep 17 00:00:00 2001 From: Bobby Sharp Date: Thu, 9 Nov 2023 13:23:56 -0500 Subject: [PATCH 13/16] Add modulePermissions to timers in module descriptor --- descriptors/ModuleDescriptor-template.json | 22 ++++++++++++------- .../swagger.api/mod-fqm-manager.yaml | 2 +- ...MaterializedViewRefreshControllerTest.java | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index f50c5528..a0e4b8e8 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -37,6 +37,11 @@ "methods": ["GET"], "pathPattern": "/entity-types/{entity-type-id}/columns/{column-name}/values", "permissionsRequired": ["fqm.entityTypes.item.columnValues.get"] + }, + { + "methods": ["POST"], + "pathPattern": "/entity-types/materialized-views/refresh", + "permissionsRequired": ["fqm.materializedViews.post"] } ] }, @@ -78,11 +83,6 @@ "methods": ["DELETE"], "pathPattern": "/query/{query-id}", "permissionsRequired": ["fqm.query.async.delete"] - }, - { - "methods": ["POST"], - "pathPattern": "/materialized-views/refresh", - "permissionsRequired": ["fqm.materializedViews.post"] } ] }, @@ -95,13 +95,19 @@ "methods": ["POST"], "pathPattern": "/query/purge", "unit": "hour", - "delay": "1" + "delay": "1", + "modulePermissions": [ + "fqm.query.purge" + ] }, { "methods": ["POST"], - "pathPattern": "/materialized-views/refresh", + "pathPattern": "/entity-types/materialized-views/refresh", "unit": "hour", - "delay": "24" + "delay": "24", + "modulePermissions": [ + "fqm.materializedViews.post" + ] } ] } diff --git a/src/main/resources/swagger.api/mod-fqm-manager.yaml b/src/main/resources/swagger.api/mod-fqm-manager.yaml index 51a3c965..c38a0739 100644 --- a/src/main/resources/swagger.api/mod-fqm-manager.yaml +++ b/src/main/resources/swagger.api/mod-fqm-manager.yaml @@ -44,7 +44,7 @@ paths: $ref: '#/components/responses/badRequestResponse' '500': $ref: '#/components/responses/internalServerErrorResponse' - /materialized-views/refresh: + /entity-types/materialized-views/refresh: post: operationId: refreshMaterializedViews tags: diff --git a/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java b/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java index baff8f67..27acab39 100644 --- a/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java +++ b/src/test/java/org/folio/fqm/controller/MaterializedViewRefreshControllerTest.java @@ -31,7 +31,7 @@ class MaterializedViewRefreshControllerTest { @Test void refreshMaterializedViewsTest() throws Exception { String tenantId = "tenant_01"; - RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/materialized-views/refresh") + RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/entity-types/materialized-views/refresh") .header(XOkapiHeaders.TENANT, tenantId) .contentType(APPLICATION_JSON); when(executionContext.getTenantId()).thenReturn(tenantId); From ada13b4ca5c4d3179ddf6ea9c50955d3fecc98bf Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Thu, 9 Nov 2023 14:10:47 -0500 Subject: [PATCH 14/16] Update NEWS --- NEWS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 59974aeb..f3145148 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,11 @@ # 1.0.x +## 1.0.3 +- [MODFQMMGR-58](https://issues.folio.org/browse/MODFQMMGR-58) Refactor drv_item_callnumber_location view +- [MODFQMMGR-76](https://issues.folio.org/browse/MODFQMMGR-76) Periodically refresh materialized views + ## 1.0.2 -- Remove the instance_titel_searchable field from the Items entity type +- Remove the instance_title_searchable field from the Items entity type - Purge old query results based on query start date/time instead of the end date/time - Fix bug in user preferred contact type - Update the provided `_tenant` interface in the module descriptor to 2.0 From e42c89d38d380863dd72154fe993381b4cdfe439 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Thu, 9 Nov 2023 14:16:37 -0500 Subject: [PATCH 15/16] [maven-release-plugin] prepare release v1.0.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0a190739..6426129b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.folio mod-fqm-manager mod-fqm-manager - 1.0.3-SNAPSHOT + 1.0.3 FOLIO Query Machine manager jar @@ -376,7 +376,7 @@ https://github.com/folio-org/${artifactId} scm:git:git://github.com/folio-org/${artifactId}.git scm:git:git@github.com:folio-org/${artifactId}.git - HEAD + v1.0.3 From ada4d0c52b1404b9456b357069645e0d8cc53b84 Mon Sep 17 00:00:00 2001 From: Matt Weaver Date: Thu, 9 Nov 2023 14:16:37 -0500 Subject: [PATCH 16/16] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6426129b..ea457a3d 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.folio mod-fqm-manager mod-fqm-manager - 1.0.3 + 1.0.4-SNAPSHOT FOLIO Query Machine manager jar @@ -376,7 +376,7 @@ https://github.com/folio-org/${artifactId} scm:git:git://github.com/folio-org/${artifactId}.git scm:git:git@github.com:folio-org/${artifactId}.git - v1.0.3 + HEAD