From b9eb41e88f5d01e491dfd1cf2cf68961949d2123 Mon Sep 17 00:00:00 2001 From: Soroosh Taefi Date: Wed, 27 Mar 2024 10:35:06 +0200 Subject: [PATCH] fix: register RouteUnifyingIndexHtmlRequestListener only when React is enabled (#2264) fix: register RouteUnifyingIndexHtmlRequestListener when React is enabled Also, this changes the behavior of client route registration so that when the views.json is not found, it only logs the absence of views.json and is gracefully skips client route registration. This is necessary as an application might have React enabled, but it is not necessarily using the FS Router. --- .../hilla/route/ClientRouteRegistry.java | 32 +++++++++++++------ .../RouteUnifyingServiceInitListener.java | 22 +++++++------ .../RouteUnifyingServiceInitListenerTest.java | 26 +++++++++++---- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/packages/java/endpoint/src/main/java/com/vaadin/hilla/route/ClientRouteRegistry.java b/packages/java/endpoint/src/main/java/com/vaadin/hilla/route/ClientRouteRegistry.java index 43db427d91..5fc07b73f0 100644 --- a/packages/java/endpoint/src/main/java/com/vaadin/hilla/route/ClientRouteRegistry.java +++ b/packages/java/endpoint/src/main/java/com/vaadin/hilla/route/ClientRouteRegistry.java @@ -28,6 +28,7 @@ import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Paths; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -116,30 +117,43 @@ public ClientViewConfig getRouteByPath(String path) { */ public void registerClientRoutes( DeploymentConfiguration deploymentConfiguration) { - try (var source = getViewsJsonAsResource(deploymentConfiguration) - .openStream()) { + var viewsJsonAsResource = getViewsJsonAsResource( + deploymentConfiguration); + if (viewsJsonAsResource == null || !Paths + .get(viewsJsonAsResource.getPath()).toFile().exists()) { + LOGGER.debug( + "No 'views.json' found either in the frontend/generated " + + "folder or in the META-INF/VAADIN folder. Skipping client " + + "route registration."); + return; + } + try (var source = viewsJsonAsResource.openStream()) { if (source != null) { clearRoutes(); registerAndRecurseChildren("", mapper.readValue(source, new TypeReference<>() { })); - } else { - LOGGER.warn("Failed to find views.json"); } } catch (IOException e) { - LOGGER.warn("Failed extract client views from views.json", e); + LOGGER.warn("Failed load client views from {}", + viewsJsonAsResource.getPath(), e); } } private URL getViewsJsonAsResource( - DeploymentConfiguration deploymentConfiguration) - throws MalformedURLException { + DeploymentConfiguration deploymentConfiguration) { var isProductionMode = deploymentConfiguration.isProductionMode(); if (isProductionMode) { return getClass().getResource("/META-INF/VAADIN/views.json"); } - return deploymentConfiguration.getFrontendFolder().toPath() - .resolve("generated").resolve("views.json").toUri().toURL(); + try { + return deploymentConfiguration.getFrontendFolder().toPath() + .resolve("generated").resolve("views.json").toUri().toURL(); + } catch (MalformedURLException e) { + LOGGER.warn("Failed to find views.json under frontend/generated", + e); + throw new RuntimeException(e); + } } private void registerAndRecurseChildren(String basePath, diff --git a/packages/java/endpoint/src/main/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListener.java b/packages/java/endpoint/src/main/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListener.java index de7b35aa0b..06dbd8897d 100644 --- a/packages/java/endpoint/src/main/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListener.java +++ b/packages/java/endpoint/src/main/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListener.java @@ -54,15 +54,17 @@ public RouteUnifyingServiceInitListener( public void serviceInit(ServiceInitEvent event) { var deploymentConfiguration = event.getSource() .getDeploymentConfiguration(); - var routeExtractionIndexHtmlRequestListener = new RouteUnifyingIndexHtmlRequestListener( - clientRouteRegistry, deploymentConfiguration); - var deploymentMode = deploymentConfiguration.isProductionMode() - ? "PRODUCTION" - : "DEVELOPMENT"; - event.addIndexHtmlRequestListener( - routeExtractionIndexHtmlRequestListener); - LOGGER.debug( - "{} mode: Registered RouteUnifyingIndexHtmlRequestListener.", - deploymentMode); + if (deploymentConfiguration.isReactEnabled()) { + var routeUnifyingIndexHtmlRequestListener = new RouteUnifyingIndexHtmlRequestListener( + clientRouteRegistry, deploymentConfiguration); + var deploymentMode = deploymentConfiguration.isProductionMode() + ? "PRODUCTION" + : "DEVELOPMENT"; + event.addIndexHtmlRequestListener( + routeUnifyingIndexHtmlRequestListener); + LOGGER.debug( + "{} mode: Registered RouteUnifyingIndexHtmlRequestListener.", + deploymentMode); + } } } diff --git a/packages/java/endpoint/src/test/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListenerTest.java b/packages/java/endpoint/src/test/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListenerTest.java index 683e7a092a..19b2015db5 100644 --- a/packages/java/endpoint/src/test/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListenerTest.java +++ b/packages/java/endpoint/src/test/java/com/vaadin/hilla/startup/RouteUnifyingServiceInitListenerTest.java @@ -41,16 +41,30 @@ public void setup() throws IOException { } @Test - public void should_addRouteIndexHtmlRequestListener() { - Assert.assertFalse("Unexpected RouteIndexHtmlRequestListener added", - eventHasAddedRouteIndexHtmlRequestListener(event)); + public void should_addRouteIndexHtmlRequestListener_when_react_is_enabled() { + Mockito.when(mockDeploymentConfiguration.isReactEnabled()) + .thenReturn(true); + + Assert.assertFalse("Unexpected RouteUnifyingServiceInitListener added", + hasRouteUnifyingIndexHtmlRequestListenerAdded(event)); routeUnifyingServiceInitListener.serviceInit(event); Assert.assertTrue( - "Expected event to have RouteIndexHtmlRequestListener added", - eventHasAddedRouteIndexHtmlRequestListener(event)); + "Expected to have RouteUnifyingServiceInitListener added", + hasRouteUnifyingIndexHtmlRequestListenerAdded(event)); + } + + @Test + public void should_not_addRouteIndexHtmlRequestListener_when_react_is_not_enabled() { + Mockito.when(mockDeploymentConfiguration.isReactEnabled()) + .thenReturn(false); + + routeUnifyingServiceInitListener.serviceInit(event); + Assert.assertFalse( + "RouteIndexHtmlRequestListener added unexpectedly when React is not enabled", + hasRouteUnifyingIndexHtmlRequestListenerAdded(event)); } - private boolean eventHasAddedRouteIndexHtmlRequestListener( + private boolean hasRouteUnifyingIndexHtmlRequestListenerAdded( ServiceInitEvent event) { return event.getAddedIndexHtmlRequestListeners().anyMatch( indexHtmlRequestListener -> indexHtmlRequestListener instanceof RouteUnifyingIndexHtmlRequestListener);