-
Notifications
You must be signed in to change notification settings - Fork 15
Feature ETP-2946: Tomcat ui detection #846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/ETP-2938-Y26
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,8 +16,44 @@ | |
| <%@ page import="org.openbravo.erpCommon.utility.OBError" %> | ||
| <%@ page import="org.openbravo.erpCommon.obps.ActivationKey.LicenseRestriction" %> | ||
| <%@ page import="org.openbravo.client.application.window.ApplicationDictionaryCachedStructures"%> | ||
| <%@ page import="org.openbravo.base.session.OBPropertiesProvider"%> | ||
| <%@ page import="java.net.HttpURLConnection"%> | ||
| <%@ page import="java.net.URL"%> | ||
| <%@ page contentType="text/html; charset=UTF-8" %> | ||
| <%@ page session="false" %> | ||
| <% | ||
| // Check if UI mode is nextgen and redirect to new UI | ||
| OBPropertiesProvider propsProvider = OBPropertiesProvider.getInstance(); | ||
| String uiMode = propsProvider.getOpenbravoProperties().getProperty("ui.mode", "classic"); | ||
|
|
||
| if ("nextgen".equalsIgnoreCase(uiMode)) { | ||
| String nextgenUrl = propsProvider.getOpenbravoProperties().getProperty("ui.url", "http://localhost:3000"); | ||
|
|
||
| // Check if new UI server is available | ||
| boolean serverAvailable = false; | ||
| try { | ||
| URL url = new URL(nextgenUrl); | ||
| HttpURLConnection connection = (HttpURLConnection) url.openConnection(); | ||
| connection.setRequestMethod("GET"); | ||
| connection.setConnectTimeout(3000); // 3 seconds timeout | ||
| connection.setReadTimeout(3000); | ||
| int responseCode = connection.getResponseCode(); | ||
| serverAvailable = (responseCode >= 200 && responseCode < 500); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion Consider catching IOException explicitly or distinguishing between connection errors and HTTP non-2xx codes. This would allow for more granular error messaging or fallback if desired in future improvements, though it is not critical in this workflow. int responseCode = connection.getResponseCode();
serverAvailable = (responseCode >= 200 && responseCode < 500);
// Consider catching IOException separately to distinguish connection failures vs. HTTP errors
connection.disconnect();Rationale: Etendo error handling patterns encourage distinguishing between common connection errors and protocol errors for robust diagnostics and future extensibility. |
||
| connection.disconnect(); | ||
| } catch (Exception e) { | ||
| serverAvailable = false; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion While it's acceptable to catch exceptions and set the server as unavailable, it may be beneficial for troubleshooting to log the exception details at least at a debug level. This is non-blocking as empty catch blocks are only blocking if errors are swallowed in a way that prevents error detection. In this context, the fallback path is clear, but some minimal logging aids support. catch (Exception e) {
serverAvailable = false;
// Consider logging exception details for diagnostics
}Rationale: Etendo exception handling best practices encourage at least some logging, even for non-critical paths, to aid debugging. The current code swallows exceptions silently. |
||
| } | ||
|
|
||
| if (serverAvailable) { | ||
| response.sendRedirect(nextgenUrl); | ||
| return; | ||
| } else { | ||
| // Redirect to error page if server is not available | ||
| response.sendRedirect("web/ui/ui-not-started.jsp"); | ||
| return; | ||
| } | ||
| } | ||
| %> | ||
| <% | ||
| /* | ||
| ************************************************************************* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,281 @@ | ||
| <%@ page import="org.openbravo.base.session.OBPropertiesProvider"%> | ||
| <%@ page contentType="text/html; charset=UTF-8" %> | ||
| <%@ page session="false" %> | ||
| <% | ||
| // Get the configured next-gen UI URL | ||
| OBPropertiesProvider propsProvider = OBPropertiesProvider.getInstance(); | ||
| String nextgenUrl = propsProvider.getOpenbravoProperties().getProperty("ui.url", "http://localhost:3000"); | ||
| %> | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>New UI Not Available - Etendo</title> | ||
| <style> | ||
| * { | ||
| margin: 0; | ||
| padding: 0; | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| body { | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; | ||
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | ||
| min-height: 100vh; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
|
|
||
| .container { | ||
| background: white; | ||
| border-radius: 12px; | ||
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | ||
| max-width: 600px; | ||
| width: 100%; | ||
| padding: 40px; | ||
| text-align: center; | ||
| } | ||
|
|
||
| .icon { | ||
| width: 80px; | ||
| height: 80px; | ||
| margin: 0 auto 24px; | ||
| background: #fee; | ||
| border-radius: 50%; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 40px; | ||
| } | ||
|
|
||
| h1 { | ||
| color: #dc2626; | ||
| font-size: 28px; | ||
| margin-bottom: 16px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| p { | ||
| color: #4b5563; | ||
| font-size: 16px; | ||
| line-height: 1.6; | ||
| margin-bottom: 12px; | ||
| } | ||
|
|
||
| .url-info { | ||
| background: #f3f4f6; | ||
| border-left: 4px solid #667eea; | ||
| padding: 16px; | ||
| margin: 24px 0; | ||
| text-align: left; | ||
| border-radius: 4px; | ||
| } | ||
|
|
||
| .url-info strong { | ||
| color: #1f2937; | ||
| display: block; | ||
| margin-bottom: 8px; | ||
| } | ||
|
|
||
| .url-info code { | ||
| background: #e5e7eb; | ||
| padding: 2px 8px; | ||
| border-radius: 4px; | ||
| font-family: 'Courier New', monospace; | ||
| color: #dc2626; | ||
| font-size: 14px; | ||
| } | ||
|
|
||
| .actions { | ||
| margin-top: 32px; | ||
| padding-top: 24px; | ||
| border-top: 1px solid #e5e7eb; | ||
| } | ||
|
|
||
| .actions h2 { | ||
| color: #1f2937; | ||
| font-size: 18px; | ||
| margin-bottom: 16px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .actions ol { | ||
| text-align: left; | ||
| padding-left: 20px; | ||
| color: #4b5563; | ||
| } | ||
|
|
||
| .actions li { | ||
| margin-bottom: 12px; | ||
| line-height: 1.6; | ||
| } | ||
|
|
||
| .actions code { | ||
| background: #f3f4f6; | ||
| padding: 2px 6px; | ||
| border-radius: 3px; | ||
| font-family: 'Courier New', monospace; | ||
| font-size: 13px; | ||
| color: #dc2626; | ||
| } | ||
|
|
||
| .btn { | ||
| display: inline-block; | ||
| margin-top: 24px; | ||
| padding: 12px 32px; | ||
| background: #667eea; | ||
| color: white; | ||
| text-decoration: none; | ||
| border-radius: 6px; | ||
| font-weight: 500; | ||
| transition: background 0.2s; | ||
| } | ||
|
|
||
| .btn:hover { | ||
| background: #5568d3; | ||
| } | ||
|
|
||
| .footer { | ||
| margin-top: 24px; | ||
| padding-top: 24px; | ||
| border-top: 1px solid #e5e7eb; | ||
| color: #6b7280; | ||
| font-size: 14px; | ||
| } | ||
|
|
||
| .dev-section { | ||
| margin-top: 32px; | ||
| padding-top: 24px; | ||
| border-top: 1px solid #e5e7eb; | ||
| background: #f9fafb; | ||
| padding: 24px; | ||
| border-radius: 8px; | ||
| text-align: left; | ||
| } | ||
|
|
||
| .dev-section h2 { | ||
| color: #1f2937; | ||
| font-size: 18px; | ||
| margin-bottom: 16px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .dev-section h3 { | ||
| color: #374151; | ||
| font-size: 16px; | ||
| margin-top: 20px; | ||
| margin-bottom: 12px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .dev-section p { | ||
| margin-bottom: 16px; | ||
| } | ||
|
|
||
| .dev-section .command-box { | ||
| background: #1f2937; | ||
| color: #10b981; | ||
| padding: 16px; | ||
| border-radius: 6px; | ||
| margin: 16px 0; | ||
| font-family: 'Courier New', monospace; | ||
| font-size: 14px; | ||
| overflow-x: auto; | ||
| } | ||
|
|
||
| .dev-section .command-box .prompt { | ||
| color: #6b7280; | ||
| user-select: none; | ||
| } | ||
|
|
||
| .dev-section .command-box .command { | ||
| color: #10b981; | ||
| } | ||
|
|
||
| .dev-section ul { | ||
| padding-left: 20px; | ||
| color: #4b5563; | ||
| } | ||
|
|
||
| .dev-section li { | ||
| margin-bottom: 8px; | ||
| line-height: 1.6; | ||
| } | ||
|
|
||
| .dev-section .note { | ||
| background: #fef3c7; | ||
| border-left: 4px solid #f59e0b; | ||
| padding: 12px 16px; | ||
| margin: 16px 0; | ||
| border-radius: 4px; | ||
| } | ||
|
|
||
| .dev-section .note strong { | ||
| color: #92400e; | ||
| display: block; | ||
| margin-bottom: 4px; | ||
| } | ||
|
|
||
| .dev-section .note p { | ||
| color: #78350f; | ||
| margin: 0; | ||
| font-size: 14px; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="container"> | ||
| <div class="icon">⚠️</div> | ||
| <h1>New UI Not Available</h1> | ||
| <p>The system is configured to use the Next-Gen UI, but the server is not available at this time.</p> | ||
|
|
||
| <div class="url-info"> | ||
| <strong>Configured URL:</strong> | ||
| <code><%=nextgenUrl%></code> | ||
| </div> | ||
|
|
||
| <div class="actions"> | ||
| <h2>What can you do?</h2> | ||
| <ol> | ||
| <li>Verify that the New UI server is running at <code><%=nextgenUrl%></code></li> | ||
| <li>If you need to start the server, run the appropriate command in your development environment</li> | ||
| <li>If you prefer to use the Classic UI temporarily, change <code>ui.mode</code> to <code>classic</code> in the <code>Openbravo.properties</code> file</li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="dev-section"> | ||
| <h2>🛠️ For Developers</h2> | ||
| <p>If you're developing on the platform and need to start the UI server:</p> | ||
|
|
||
| <h3>Start UI Server</h3> | ||
| <div class="command-box"> | ||
| <span class="prompt">$</span> <span class="command">./gradlew ui</span> | ||
| </div> | ||
|
|
||
| <p>This will start the development server on <code><%=nextgenUrl%></code></p> | ||
|
|
||
| <h3>Stop Server</h3> | ||
| <p>Press <strong>Ctrl+C</strong> in the terminal to stop the server.</p> | ||
|
|
||
| <h3>Other Commands</h3> | ||
| <div class="command-box"> | ||
| <span class="prompt">$</span> <span class="command">./gradlew uiInstall</span><br> | ||
| <span style="color: #6b7280;"># Install dependencies</span> | ||
| </div> | ||
| <div class="command-box"> | ||
| <span class="prompt">$</span> <span class="command">./gradlew uiBuild</span><br> | ||
| <span style="color: #6b7280;"># Build for production</span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <a href="../../index.jsp" class="btn">Retry</a> | ||
|
|
||
| <div class="footer"> | ||
| If the problem persists, contact your system administrator | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning
The
catch (Exception e) {}block is empty, which is a critical issue. All exceptions must be handled, at least by logging them, to prevent silently masking potential problems. Additionally, theHttpURLConnectionshould be disconnected in afinallyblock to ensure resources are released even if an exception occurs.Rationale: Empty catch blocks are a common source of hidden bugs and make debugging extremely difficult. Proper logging is essential for error detection and system monitoring. Furthermore, not explicitly disconnecting
HttpURLConnectioncan lead to resource leaks and connection exhaustion over time. The Etendo best practices for exception handling often involve logging and rethrowingOBExceptionor similar framework-specific exceptions.