This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit ce42b1f871544ec4863fde2da45f699ab18b7313
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun May 24 11:50:54 2026 -0400

    CAY-2949 CayenneModeler MCP: dbimport_run tool
    
    no need to check for <reveng> section
---
 cayenne-mcp-server/PROTOCOL.md                     | 21 +++++----
 .../mcp/tools/dbimport/DbImportRunTool.java        | 50 +++++++++-------------
 .../tools/dbimport/protocol/DbImportErrorCode.java |  1 -
 .../dbimport/protocol/DbImportValidation.java      |  3 +-
 .../cayenne/mcp/tools/dbimport/DbImportRunIT.java  |  1 -
 .../mcp/tools/dbimport/DbImportRunMcpIT.java       |  3 --
 .../tools/dbimport/DbImportRunValidationTest.java  | 18 ++++----
 7 files changed, 39 insertions(+), 58 deletions(-)

diff --git a/cayenne-mcp-server/PROTOCOL.md b/cayenne-mcp-server/PROTOCOL.md
index 4842929dc..b5d78d764 100644
--- a/cayenne-mcp-server/PROTOCOL.md
+++ b/cayenne-mcp-server/PROTOCOL.md
@@ -64,7 +64,7 @@ Both fields are required.
 
 ## `dbimport_run`
 
-Runs Cayenne reverse-engineering (dbimport) for a named DataMap. Reads the 
`<reverse-engineering>` filter config from the DataMap XML and reads JDBC 
connection info from the DBConnector that CayenneModeler stored in preferences 
for this DataMap. Rewrites the DataMap XML on disk with the merged schema.
+Runs Cayenne reverse-engineering (dbimport) for a named DataMap. Reads JDBC 
connection info from the DBConnector that CayenneModeler stored in preferences 
for this DataMap. If the DataMap has a `<reverse-engineering>` block its 
filters are applied; otherwise the full database schema is imported. Rewrites 
the DataMap XML on disk with the merged schema.
 
 ### Input
 
@@ -75,7 +75,7 @@ Runs Cayenne reverse-engineering (dbimport) for a named 
DataMap. Reads the `<rev
 }
 ```
 
-Both fields are required. JDBC URL, driver, credentials, and schema filters 
are not inputs — they come from CayenneModeler preferences and the DataMap's 
`<reverse-engineering>` block respectively.
+Both fields are required. JDBC URL, driver, and credentials are not inputs — 
they come from CayenneModeler preferences. Schema filters come from the 
DataMap's `<reverse-engineering>` block if present.
 
 ### Output
 
@@ -98,15 +98,14 @@ Both fields are required. JDBC URL, driver, credentials, 
and schema filters are
   },
   "warnings": ["string (captured WARN-level log lines from 
org.apache.cayenne.dbsync)"],
   "validation": {
-    "projectFound":                    true,
-    "dataMapFound":                    true,
-    "reverseEngineeringConfigPresent": true,
-    "dbConnectorPresent":              true,
-    "jdbcDriverLoadable":              true,
-    "jdbcConnectionOpened":            true
+    "projectFound":       true,
+    "dataMapFound":       true,
+    "dbConnectorPresent": true,
+    "jdbcDriverLoadable": true,
+    "jdbcConnectionOpened": true
   },
   "error": {
-    "code":    "project_not_found | project_parse_failed | datamap_not_found | 
reverse_engineering_config_missing | dbconnector_not_configured | 
jdbc_driver_not_loadable | jdbc_connection_failed | dbimport_runtime_error",
+    "code":    "project_not_found | project_parse_failed | datamap_not_found | 
dbconnector_not_configured | jdbc_driver_not_loadable | jdbc_connection_failed 
| dbimport_runtime_error",
     "message": "string"
   }
 }
@@ -119,8 +118,8 @@ Both fields are required. JDBC URL, driver, credentials, 
and schema filters are
 - `error` — validation passed but dbimport threw mid-run; `summary` reflects 
counters captured before the failure
 
 `resolved` notes:
-- Populated as soon as the connector is resolved (validation step 5), so it is 
present even on `jdbc_driver_not_loadable` and `jdbc_connection_failed` 
failures.
-- `null` only when validation fails before the connector is read (steps 1–4).
+- Populated as soon as the connector is resolved (validation step 4), so it is 
present even on `jdbc_driver_not_loadable` and `jdbc_connection_failed` 
failures.
+- `null` only when validation fails before the connector is read (steps 1–3).
 - Never contains `userName` or `password`.
 
 `summary` notes:
diff --git 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunTool.java
 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunTool.java
index a158ae0ed..a73b10b40 100644
--- 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunTool.java
+++ 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunTool.java
@@ -22,13 +22,11 @@ import io.modelcontextprotocol.json.McpJsonMapper;
 import io.modelcontextprotocol.server.McpServerFeatures;
 import io.modelcontextprotocol.spec.McpSchema;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
-import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.datasource.DriverDataSource;
 import org.apache.cayenne.dbsync.DbSyncModule;
 import org.apache.cayenne.dbsync.reverse.configuration.ToolsModule;
 import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
 import org.apache.cayenne.dbsync.reverse.dbimport.DbImportModule;
-import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.map.DataMap;
@@ -68,9 +66,10 @@ import java.util.stream.Collectors;
 
 /**
  * MCP tool that runs Cayenne dbimport for a single DataMap inside a Cayenne 
project.
- * Reads reverse-engineering filter config from the DataMap's {@code 
<reverse-engineering>}
- * block and JDBC connection info from the DBConnector stored in 
CayenneModeler preferences
- * for this DataMap. Returns a structured JSON summary of what changed.
+ * Reads JDBC connection info from the DBConnector stored in CayenneModeler 
preferences for
+ * this DataMap. If the DataMap has a {@code <reverse-engineering>} block its 
filters are
+ * applied; otherwise the full database schema is imported. Returns a 
structured JSON summary
+ * of what changed.
  *
  * @since 5.0
  */
@@ -106,11 +105,12 @@ public class DbImportRunTool {
                 NAME,
                 null,
                 """
-                        Run Cayenne dbimport for a named DataMap. Reads 
reverse-engineering filters \
-                        from the DataMap's <reverse-engineering> block and 
JDBC connection from the \
-                        DBConnector that CayenneModeler stored for this 
DataMap. Returns token-count \
-                        summary and resolved connection metadata; actual 
schema changes are written \
-                        to the DataMap XML on disk.""",
+                        Run Cayenne dbimport for a named DataMap. Reads JDBC 
connection from the \
+                        DBConnector stored for this DataMap in CayenneModeler 
preferences. If the \
+                        DataMap has a <reverse-engineering> block its filters 
are applied; otherwise \
+                        the full database schema is imported. Returns 
token-count summary and \
+                        resolved connection metadata; actual schema changes 
are written to the \
+                        DataMap XML on disk.""",
                 new McpSchema.JsonSchema(
                         "object",
                         Map.of(
@@ -157,7 +157,7 @@ public class DbImportRunTool {
         if (!Files.isReadable(projectFile)) {
             return validationFailed(DbImportErrorCode.project_not_found,
                     "No readable file at %s".formatted(projectPath),
-                    new DbImportValidation(false, null, null, null, null, 
null));
+                    new DbImportValidation(false, null, null, null, null));
         }
 
         // Step 2 — parses as Cayenne project?
@@ -170,7 +170,7 @@ public class DbImportRunTool {
         } catch (Exception e) {
             return validationFailed(DbImportErrorCode.project_parse_failed,
                     "Cayenne project loader rejected the descriptor: 
%s".formatted(e.getMessage()),
-                    new DbImportValidation(true, null, null, null, null, 
null));
+                    new DbImportValidation(true, null, null, null, null));
         }
 
         // Step 3 — DataMap present?
@@ -184,23 +184,13 @@ public class DbImportRunTool {
             return validationFailed(DbImportErrorCode.datamap_not_found,
                     "Project loaded successfully but contains no DataMap named 
'%s'. Available DataMaps: %s."
                             .formatted(dataMapName, available),
-                    new DbImportValidation(true, false, null, null, null, 
null));
-        }
-
-        // Step 4 — <reverse-engineering> config present?
-        DataChannelMetaData metaData = 
injector.getInstance(DataChannelMetaData.class);
-        ReverseEngineering reverseEngineering = metaData.get(dataMap, 
ReverseEngineering.class);
-        if (reverseEngineering == null) {
-            return 
validationFailed(DbImportErrorCode.reverse_engineering_config_missing,
-                    "DataMap '%s' has no <reverse-engineering> configuration. 
Configure dbimport for this DataMap in CayenneModeler before invoking the tool."
-                            .formatted(dataMapName),
-                    new DbImportValidation(true, true, false, null, null, 
null));
+                    new DbImportValidation(true, false, null, null, null));
         }
 
         // Resolve DataMap file path for preference node lookup
         Path dataMapFile = resolveDataMapFile(dataMap);
 
-        // Step 5 — DBConnector stored in preferences?
+        // Step 4 — DBConnector stored in preferences?
         String dataMapId = 
PreferenceNodeIds.idForPath(dataMapFile.toAbsolutePath().toString());
         DBConnector connector = new 
DataMapPrefs(prefsLocator.dataMapNode(dataMapId)).getConnector();
         if (connector == null) {
@@ -211,7 +201,7 @@ public class DbImportRunTool {
                             choose 'Reengineer Database Schema…', and pick a 
connection — \
                             its values will be saved to this DataMap's 
preferences.\
                             """.formatted(dataMapName, projectPath),
-                    new DbImportValidation(true, true, true, false, null, 
null));
+                    new DbImportValidation(true, true, false, null, null));
         }
 
         DbImportResolved resolved = new DbImportResolved(
@@ -221,7 +211,7 @@ public class DbImportRunTool {
                 connector.getDbAdapter()
         );
 
-        // Step 6 — JDBC driver loadable from Preferences → Classpath?
+        // Step 5 — JDBC driver loadable from Preferences → Classpath?
         ClassLoader driverCl = buildDriverClassLoader();
         Driver driver;
         try {
@@ -230,17 +220,17 @@ public class DbImportRunTool {
             return validationFailed(DbImportErrorCode.jdbc_driver_not_loadable,
                     "JDBC driver class '%s' could not be loaded. In 
CayenneModeler, open Preferences → Classpath, add the driver jar, then re-run — 
the MCP server reads the classpath fresh on each call."
                             .formatted(connector.getJdbcDriver()),
-                    new DbImportValidation(true, true, true, true, false, 
null),
+                    new DbImportValidation(true, true, true, false, null),
                     resolved);
         } catch (Exception e) {
             return validationFailed(DbImportErrorCode.jdbc_driver_not_loadable,
                     "JDBC driver class '%s' could not be instantiated: %s"
                             .formatted(connector.getJdbcDriver(), 
e.getMessage()),
-                    new DbImportValidation(true, true, true, true, false, 
null),
+                    new DbImportValidation(true, true, true, false, null),
                     resolved);
         }
 
-        // Step 7 — JDBC connection opens?
+        // Step 6 — JDBC connection opens?
         Connection conn;
         try {
             conn = new DriverDataSource(
@@ -254,7 +244,7 @@ public class DbImportRunTool {
             return validationFailed(DbImportErrorCode.jdbc_connection_failed,
                     "Could not open JDBC connection to '%s' as '%s': %s%s."
                             .formatted(connector.getUrl(), 
connector.getUserName(), e.getMessage(), sqlState),
-                    new DbImportValidation(true, true, true, true, true, 
false),
+                    new DbImportValidation(true, true, true, true, false),
                     resolved);
         }
 
diff --git 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportErrorCode.java
 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportErrorCode.java
index 352a6d351..c7a672f9f 100644
--- 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportErrorCode.java
+++ 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportErrorCode.java
@@ -22,7 +22,6 @@ public enum DbImportErrorCode {
     project_not_found,
     project_parse_failed,
     datamap_not_found,
-    reverse_engineering_config_missing,
     dbconnector_not_configured,
     jdbc_driver_not_loadable,
     jdbc_connection_failed,
diff --git 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportValidation.java
 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportValidation.java
index f869b3f11..e48bc4979 100644
--- 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportValidation.java
+++ 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/dbimport/protocol/DbImportValidation.java
@@ -27,10 +27,9 @@ package org.apache.cayenne.mcp.tools.dbimport.protocol;
 public record DbImportValidation(
         Boolean projectFound,
         Boolean dataMapFound,
-        Boolean reverseEngineeringConfigPresent,
         Boolean dbConnectorPresent,
         Boolean jdbcDriverLoadable,
         Boolean jdbcConnectionOpened
 ) {
-    public static final DbImportValidation ALL_PASSED = new 
DbImportValidation(true, true, true, true, true, true);
+    public static final DbImportValidation ALL_PASSED = new 
DbImportValidation(true, true, true, true, true);
 }
diff --git 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunIT.java
 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunIT.java
index caf34e10b..4f5100445 100644
--- 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunIT.java
+++ 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunIT.java
@@ -115,7 +115,6 @@ public class DbImportRunIT {
 
         assertTrue(result.validation().projectFound());
         assertTrue(result.validation().dataMapFound());
-        assertTrue(result.validation().reverseEngineeringConfigPresent());
         assertTrue(result.validation().dbConnectorPresent());
         assertTrue(result.validation().jdbcDriverLoadable());
         assertTrue(result.validation().jdbcConnectionOpened());
diff --git 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunMcpIT.java
 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunMcpIT.java
index 10ffa610e..13bbef7f3 100644
--- 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunMcpIT.java
+++ 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunMcpIT.java
@@ -144,7 +144,6 @@ public class DbImportRunMcpIT {
                   "validation" : {
                     "projectFound" : false,
                     "dataMapFound" : null,
-                    "reverseEngineeringConfigPresent" : null,
                     "dbConnectorPresent" : null,
                     "jdbcDriverLoadable" : null,
                     "jdbcConnectionOpened" : null
@@ -184,7 +183,6 @@ public class DbImportRunMcpIT {
                   "validation" : {
                     "projectFound" : true,
                     "dataMapFound" : true,
-                    "reverseEngineeringConfigPresent" : true,
                     "dbConnectorPresent" : true,
                     "jdbcDriverLoadable" : true,
                     "jdbcConnectionOpened" : true
@@ -225,7 +223,6 @@ public class DbImportRunMcpIT {
                   "validation" : {
                     "projectFound" : true,
                     "dataMapFound" : true,
-                    "reverseEngineeringConfigPresent" : true,
                     "dbConnectorPresent" : true,
                     "jdbcDriverLoadable" : true,
                     "jdbcConnectionOpened" : true
diff --git 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunValidationTest.java
 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunValidationTest.java
index c4f09307c..0c13205f7 100644
--- 
a/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunValidationTest.java
+++ 
b/cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/dbimport/DbImportRunValidationTest.java
@@ -70,7 +70,6 @@ public class DbImportRunValidationTest {
         assertEquals(DbImportErrorCode.project_not_found, 
result.error().code());
         assertFalse(result.validation().projectFound());
         assertNull(result.validation().dataMapFound());
-        assertNull(result.validation().reverseEngineeringConfigPresent());
         assertNull(result.validation().dbConnectorPresent());
         assertNull(result.validation().jdbcDriverLoadable());
         assertNull(result.validation().jdbcConnectionOpened());
@@ -89,7 +88,6 @@ public class DbImportRunValidationTest {
         assertEquals(DbImportErrorCode.project_parse_failed, 
result.error().code());
         assertTrue(result.validation().projectFound());
         assertNull(result.validation().dataMapFound());
-        assertNull(result.validation().reverseEngineeringConfigPresent());
         assertNull(result.validation().dbConnectorPresent());
         assertNull(result.validation().jdbcDriverLoadable());
         assertNull(result.validation().jdbcConnectionOpened());
@@ -108,7 +106,6 @@ public class DbImportRunValidationTest {
         assertTrue(result.error().message().contains("TestMap"), "Available 
maps should be listed");
         assertTrue(result.validation().projectFound());
         assertFalse(result.validation().dataMapFound());
-        assertNull(result.validation().reverseEngineeringConfigPresent());
         assertNull(result.validation().dbConnectorPresent());
         assertNull(result.validation().jdbcDriverLoadable());
         assertNull(result.validation().jdbcConnectionOpened());
@@ -116,17 +113,19 @@ public class DbImportRunValidationTest {
     }
 
     @Test
-    public void reverseEngineeringConfigMissing() throws URISyntaxException {
-        String projectPath = fixtureProject("no-dbimport");
+    public void noReverseEngineeringProceedsThroughToConnectorCheck(@TempDir 
Path tmp) throws IOException {
+        Path projectFile = copyFixture("no-dbimport", tmp);
+        Preferences isolatedRoot = isolatedPrefsRoot();
 
-        DbImportRunResult result = tool.run(projectPath, "TestMap");
+        DbImportRunTool isolatedTool = new DbImportRunTool(new 
PrefsLocator(isolatedRoot));
+        DbImportRunResult result = isolatedTool.run(projectFile.toString(), 
"TestMap");
 
+        // Should not fail on missing reverse-engineering — proceeds to 
connector check instead
         assertEquals("validation_failed", result.status());
-        assertEquals(DbImportErrorCode.reverse_engineering_config_missing, 
result.error().code());
+        assertEquals(DbImportErrorCode.dbconnector_not_configured, 
result.error().code());
         assertTrue(result.validation().projectFound());
         assertTrue(result.validation().dataMapFound());
-        assertFalse(result.validation().reverseEngineeringConfigPresent());
-        assertNull(result.validation().dbConnectorPresent());
+        assertFalse(result.validation().dbConnectorPresent());
         assertNull(result.validation().jdbcDriverLoadable());
         assertNull(result.validation().jdbcConnectionOpened());
         assertNoCredentialsInResult(result);
@@ -145,7 +144,6 @@ public class DbImportRunValidationTest {
         assertEquals(DbImportErrorCode.dbconnector_not_configured, 
result.error().code());
         assertTrue(result.validation().projectFound());
         assertTrue(result.validation().dataMapFound());
-        assertTrue(result.validation().reverseEngineeringConfigPresent());
         assertFalse(result.validation().dbConnectorPresent());
         assertNull(result.validation().jdbcDriverLoadable());
         assertNull(result.validation().jdbcConnectionOpened());

Reply via email to