diff --git a/CHANGELOG.md b/CHANGELOG.md index 03ea8033..e5a52cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to Data Hopper EDW (formerly hop-datavault) are documented i ## Unreleased +### SCD2 table dialog OK is not blocked by configuration errors (issue #137) + +- Closing the Business Vault SCD2 table dialog with **OK** still shows validation errors, then offers **Save the table anyway?** +- Model and satellite configuration issues (missing target database, open-end sentinel, and similar) no longer force **Cancel** and lost edits +- **Validate** and **Check model** still report the same errors; Business Vault Update still fails until they are fixed + ### Relationship lines prefer side attachments (issue #135) - Table-to-table relationship lines stay on left/right edges until about 50° of inclination (was ~25–30° for typical wide cards) diff --git a/docs/help/bv-scd2-table-dialog.adoc b/docs/help/bv-scd2-table-dialog.adoc index 40cdc9bd..b03e7114 100644 --- a/docs/help/bv-scd2-table-dialog.adoc +++ b/docs/help/bv-scd2-table-dialog.adoc @@ -127,6 +127,7 @@ Longer guidance: project doc `docs/business-vault-scd2.adoc` (section *Type 1 vs == Tips +- **OK** can save the table even when Check reports errors. Some issues live in Business Vault or Data Vault configuration and cannot be fixed in this dialog. Use **Validate** or **Check model** to review them; **Business Vault Update** still fails until they are fixed. - Run **Check model** on the `.hbv` file before **Business Vault Update** or Debug. - Confirm **Data Vault target** (read satellites) and **Business Vault target** (write SCD2) connections both resolve in project metadata. - After changing the linked `.hdv` on disk, use **Reload DV model** on the Business Vault toolbar. diff --git a/src/main/java/org/hopper/edw/datavault/hopgui/file/businessvault/HopGuiBvScd2TableDialog.java b/src/main/java/org/hopper/edw/datavault/hopgui/file/businessvault/HopGuiBvScd2TableDialog.java index be685dcf..27a15ca4 100644 --- a/src/main/java/org/hopper/edw/datavault/hopgui/file/businessvault/HopGuiBvScd2TableDialog.java +++ b/src/main/java/org/hopper/edw/datavault/hopgui/file/businessvault/HopGuiBvScd2TableDialog.java @@ -31,6 +31,7 @@ import org.apache.hop.ui.core.PropsUi; import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.dialog.MessageBox; import org.apache.hop.ui.core.gui.WindowProperty; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; @@ -767,24 +768,36 @@ private void applyDerivativesToTable(BvScd2Table target) { } private void ok() { - applyWidgetsToTable(input); - + BvScd2Table draft = new BvScd2Table(); + applyWidgetsToTable(draft); List remarks = BvScd2FieldMappingDialogSupport.validateForDialog( - input, businessVaultModel, dataVaultModel, variables); - if (BvScd2FieldMappingDialogSupport.hasValidationErrors(remarks)) { - new ErrorDialog( - shell, - BaseMessages.getString(PKG, "HopGuiBvScd2TableDialog.ValidationError.Title"), - BvScd2FieldMappingDialogSupport.formatValidationErrors(remarks), - null); + draft, businessVaultModel, dataVaultModel, variables); + if (BvScd2FieldMappingDialogSupport.hasValidationErrors(remarks) + && !confirmSaveWithValidationErrors(remarks)) { return; } + applyWidgetsToTable(input); ok = true; dispose(); } + /** + * Shows check errors without discarding dialog edits. Some remarks come from model or satellite + * configuration that cannot be fixed in this shell. + */ + private boolean confirmSaveWithValidationErrors(List remarks) { + MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_WARNING); + box.setText(BaseMessages.getString(PKG, "HopGuiBvScd2TableDialog.ValidationError.Title")); + box.setMessage( + BaseMessages.getString( + PKG, + "HopGuiBvScd2TableDialog.ValidationError.SaveAnyway", + BvScd2FieldMappingDialogSupport.formatValidationErrors(remarks))); + return box.open() == SWT.YES; + } + private void validate() { try { List remarks = diff --git a/src/main/resources/org/hopper/edw/datavault/hopgui/file/businessvault/messages/messages_en_US.properties b/src/main/resources/org/hopper/edw/datavault/hopgui/file/businessvault/messages/messages_en_US.properties index 0de7e013..00baca8c 100644 --- a/src/main/resources/org/hopper/edw/datavault/hopgui/file/businessvault/messages/messages_en_US.properties +++ b/src/main/resources/org/hopper/edw/datavault/hopgui/file/businessvault/messages/messages_en_US.properties @@ -154,6 +154,7 @@ HopGuiBvScd2TableDialog.SatelliteSettings.Column.Satellite=Satellite HopGuiBvScd2TableDialog.SatelliteSettings.Column.FunctionalTimestamp=Functional timestamp override HopGuiBvScd2TableDialog.SatelliteSettings.Column.SourceIndicator=Source indicator value HopGuiBvScd2TableDialog.ValidationError.Title=SCD2 table validation failed +HopGuiBvScd2TableDialog.ValidationError.SaveAnyway=The SCD2 table has validation issues. Some of them belong to model or satellite configuration and cannot be fixed in this dialog.\n\n{0}\n\nSave the table anyway? HopGuiBusinessVaultGraph.Context.Background.Message=Add Data Vault references, Business Vault tables, or another action: HopGuiBusinessVaultGraph.Context.AddHubReference.Name=Add Linked Hub diff --git a/src/test/java/org/hopper/edw/datavault/metadata/businessvault/BvScd2FieldMappingDialogSupportTest.java b/src/test/java/org/hopper/edw/datavault/metadata/businessvault/BvScd2FieldMappingDialogSupportTest.java index bbec6fce..edb43ee4 100644 --- a/src/test/java/org/hopper/edw/datavault/metadata/businessvault/BvScd2FieldMappingDialogSupportTest.java +++ b/src/test/java/org/hopper/edw/datavault/metadata/businessvault/BvScd2FieldMappingDialogSupportTest.java @@ -29,7 +29,9 @@ import org.apache.hop.core.xml.XmlHandler; import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil; import org.hopper.edw.datavault.metadata.DataVaultModel; +import org.hopper.edw.datavault.metadata.DvSatellite; import org.hopper.edw.datavault.metadata.DvTableType; +import org.hopper.edw.datavault.metadata.SatelliteAttribute; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.w3c.dom.Document; @@ -128,6 +130,36 @@ void validateForDialogReportsMultiSatelliteMappingErrors() throws Exception { BvScd2FieldMappingDialogSupport.formatValidationErrors(remarks).contains("field mappings")); } + @Test + void validateForDialogReportsModelConfigurationErrors() { + BvScd2Table table = new BvScd2Table(); + table.setName("customer_scd2"); + table.setTableName("customer_scd2"); + table.setBuildMode(BvScd2BuildMode.INCREMENTAL); + table.setFunctionalTimestampField("LOAD_DATE"); + table.getDerivatives().add(new BvDerivativeRef("sat_customer", DvTableType.SATELLITE)); + + BusinessVaultConfiguration bvConfig = new BusinessVaultConfiguration(); + bvConfig.setOpenEndSentinel(""); + bvConfig.setTargetDatabase(""); + BusinessVaultModel bvModel = new BusinessVaultModel(); + bvModel.setConfiguration(bvConfig); + + DataVaultModel dvModel = new DataVaultModel(); + DvSatellite satellite = new DvSatellite("sat_customer"); + satellite.setHubName("hub_customer"); + satellite.getAttributes().add(new SatelliteAttribute("segment")); + dvModel.getTables().add(satellite); + + List remarks = + BvScd2FieldMappingDialogSupport.validateForDialog(table, bvModel, dvModel, new Variables()); + + assertTrue(BvScd2FieldMappingDialogSupport.hasValidationErrors(remarks)); + String formatted = BvScd2FieldMappingDialogSupport.formatValidationErrors(remarks); + assertTrue(formatted.contains("open-end sentinel")); + assertTrue(formatted.contains("target database")); + } + private static BvScd2Table customer360Table() { BvScd2Table table = new BvScd2Table(); table.setName("customer_360_bv");