@@ -967,4 +967,90 @@ public void testUseUserTimeZone() throws Exception {
967967 }
968968
969969 }
970+
971+ @ Test (groups = {"integration" })
972+ public void testEndpointUrlPathIsPreserved () throws Exception {
973+ if (isCloud ()) {
974+ return ; // mocked server
975+ }
976+
977+ WireMockServer mockServer = new WireMockServer (WireMockConfiguration
978+ .options ().port (9090 ).notifier (new ConsoleNotifier (false )));
979+ mockServer .start ();
980+
981+ try {
982+ // From wireshark dump as C Array - response for SELECT currentUser() AS user, timezone() AS timezone, version() AS version LIMIT 1
983+ char selectServerInfo [] = {
984+ 0x03 , 0x04 , 0x75 , 0x73 , 0x65 , 0x72 , 0x08 , 0x74 ,
985+ 0x69 , 0x6d , 0x65 , 0x7a , 0x6f , 0x6e , 0x65 , 0x07 ,
986+ 0x76 , 0x65 , 0x72 , 0x73 , 0x69 , 0x6f , 0x6e , 0x06 ,
987+ 0x53 , 0x74 , 0x72 , 0x69 , 0x6e , 0x67 , 0x06 , 0x53 ,
988+ 0x74 , 0x72 , 0x69 , 0x6e , 0x67 , 0x06 , 0x53 , 0x74 ,
989+ 0x72 , 0x69 , 0x6e , 0x67 , 0x07 , 0x64 , 0x65 , 0x66 ,
990+ 0x61 , 0x75 , 0x6c , 0x74 , 0x03 , 0x55 , 0x54 , 0x43 ,
991+ 0x0b , 0x32 , 0x34 , 0x2e , 0x33 , 0x2e , 0x31 , 0x2e ,
992+ 0x32 , 0x36 , 0x37 , 0x32 };
993+
994+ char select1Res [] = {
995+ 0x01 , 0x01 , 0x31 , 0x05 , 0x55 , 0x49 , 0x6e , 0x74 ,
996+ 0x38 , 0x01 };
997+
998+ // URL format: jdbc:clickhouse://host:port/http_path/database
999+ // For /sales/db: http_path=/sales, database=db
1000+ // For /billing/db: http_path=/billing, database=db
1001+
1002+ // Setup stubs for sales virtual instance (path: /sales)
1003+ mockServer .addStubMapping (WireMock .post (WireMock .urlPathEqualTo ("/sales" ))
1004+ .withRequestBody (WireMock .matching (".*SELECT 1.*" ))
1005+ .willReturn (WireMock .ok (new String (select1Res ))
1006+ .withHeader ("X-ClickHouse-Summary" ,
1007+ "{ \" read_bytes\" : \" 100\" , \" read_rows\" : \" 10\" }" )).build ());
1008+
1009+ mockServer .addStubMapping (WireMock .post (WireMock .urlPathEqualTo ("/sales" ))
1010+ .withRequestBody (WireMock .equalTo ("SELECT currentUser() AS user, timezone() AS timezone, version() AS version LIMIT 1" ))
1011+ .willReturn (WireMock .ok (new String (selectServerInfo ))
1012+ .withHeader ("X-ClickHouse-Summary" ,
1013+ "{ \" read_bytes\" : \" 10\" , \" read_rows\" : \" 1\" }" )).build ());
1014+
1015+ // Setup stubs for billing virtual instance (path: /billing)
1016+ mockServer .addStubMapping (WireMock .post (WireMock .urlPathEqualTo ("/billing" ))
1017+ .withRequestBody (WireMock .matching (".*SELECT 2.*" ))
1018+ .willReturn (WireMock .ok (new String (select1Res ))
1019+ .withHeader ("X-ClickHouse-Summary" ,
1020+ "{ \" read_bytes\" : \" 200\" , \" read_rows\" : \" 20\" }" )).build ());
1021+
1022+ mockServer .addStubMapping (WireMock .post (WireMock .urlPathEqualTo ("/billing" ))
1023+ .withRequestBody (WireMock .equalTo ("SELECT currentUser() AS user, timezone() AS timezone, version() AS version LIMIT 1" ))
1024+ .willReturn (WireMock .ok (new String (selectServerInfo ))
1025+ .withHeader ("X-ClickHouse-Summary" ,
1026+ "{ \" read_bytes\" : \" 10\" , \" read_rows\" : \" 1\" }" )).build ());
1027+
1028+ Properties properties = new Properties ();
1029+ properties .put ("compress" , "false" );
1030+
1031+ // Test sales virtual instance: /sales/db means http_path=/sales, database=db
1032+ String salesJdbcUrl = "jdbc:clickhouse://localhost:" + mockServer .port () + "/sales/db" ;
1033+ try (Connection conn = new ConnectionImpl (salesJdbcUrl , properties );
1034+ Statement stmt = conn .createStatement ();
1035+ ResultSet rs = stmt .executeQuery ("SELECT 1" )) {
1036+ Assert .assertTrue (rs .next ());
1037+ Assert .assertEquals (rs .getInt (1 ), 1 );
1038+ }
1039+
1040+ // Test billing virtual instance: /billing/db means http_path=/billing, database=db
1041+ String billingJdbcUrl = "jdbc:clickhouse://localhost:" + mockServer .port () + "/billing/db" ;
1042+ try (Connection conn = new ConnectionImpl (billingJdbcUrl , properties );
1043+ Statement stmt = conn .createStatement ();
1044+ ResultSet rs = stmt .executeQuery ("SELECT 2" )) {
1045+ Assert .assertTrue (rs .next ());
1046+ }
1047+
1048+ // Verify requests were made to the correct HTTP paths (/sales and /billing, not /sales/db)
1049+ mockServer .verify (WireMock .postRequestedFor (WireMock .urlPathEqualTo ("/sales" )));
1050+ mockServer .verify (WireMock .postRequestedFor (WireMock .urlPathEqualTo ("/billing" )));
1051+
1052+ } finally {
1053+ mockServer .stop ();
1054+ }
1055+ }
9701056}
0 commit comments