Skip to content
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

chore: add etag in consolidated api controller #38873

Merged
merged 20 commits into from
Jan 30, 2025

Conversation

dvj1988
Copy link
Contributor

@dvj1988 dvj1988 commented Jan 28, 2025

Description

  • Implement Etag caching for consolidated api in view mode.
    • Generate Etag for consolidated api in view mode
    • compare the if none match header with the computed etag and respond with either a 304 or 200
    • add span for generate etag fn
  • Remove prefetching and caching of static assets in service worker
sequenceDiagram
    Client->>Server: Request Consolidated API
    Server-->>Server: Compute ETag
    Server-->>Client: Respond with ETag, Cache-Control
    Client->>Server: Subsequent Request with If-None-Match
    alt ETag Matches
        Server-->>Client: 304 Not Modified
    else ETag Different
        Server-->>Client: Full Response with New ETag
    end
Loading

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13046610688
Commit: c14d58d
Cypress dashboard.
Tags: @tag.All
Spec:


Thu, 30 Jan 2025 07:14:21 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Added ETag support for consolidated API responses to improve caching efficiency.
    • Introduced a new route handler for the /api/v1/consolidated-api/view endpoint.
  • Performance Improvements

    • Optimized NGINX configuration for API responses.
    • Updated tracing endpoint for better monitoring.
  • Dependency Updates

    • Added Jackson datatype support for Java 8 date and time handling.
  • Technical Enhancements

    • Improved request handling in ConsolidatedAPIController.
    • Updated service worker configuration.
    • Refined feature flag handling in the client.
    • Enhanced API request headers for consolidated page load functions.
    • Simplified caching and routing logic in the service worker.
    • Adjusted service worker caching strategy for production environment.
    • Updated test specification path for Cypress limited tests.
    • Modified request handling to remove unnecessary headers in feature flag functions.

Copy link
Contributor

coderabbitai bot commented Jan 28, 2025

Walkthrough

This pull request introduces significant changes to Appsmith's caching strategies, service worker configuration, API response handling, and tracing setup. Key modifications include a shift from pre-caching to a more streamlined caching approach in the service worker, the addition of ETag support for API responses, and updates to the OpenTelemetry tracing endpoint. These changes collectively enhance the application's performance and observability.

Changes

File Change Summary
app/client/craco.build.config.js Modified Webpack build configuration for service worker, changing mode to production and adjusting file caching exclusions.
app/client/src/serviceWorker.ts Removed pre-caching strategies, simplified routing, and cache management.
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java Added new ETAG_SPAN constant for tracing.
app/server/appsmith-server/pom.xml Added jackson-datatype-jsr310 dependency for Java 8 date/time support.
app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java Updated method to support ETag and conditional requests.
app/server/appsmith-server/src/main/resources/application.properties Updated OpenTelemetry tracing endpoint.
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCE.java Added method for computing ETag for consolidated API responses.
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java Implemented ETag computation logic for API responses.
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java Updated constructor to include ObservationHelper.
deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs Added new route handler for /api/v1/consolidated-api/view.
app/client/cypress/limited-tests.txt Updated test specification path to focus on a specific test case.
app/client/cypress/support/Objects/FeatureFlags.ts Enhanced intercept logic for feature flags handling.
app/client/src/api/services/ConsolidatedPageLoadApi/api.ts Added headers to API requests for consolidated page load data.
app/client/cypress/support/Pages/AggregateHelper.ts Replaced custom sleep with Cypress's wait for page refresh.

Possibly related PRs

Suggested Labels

Enhancement, Bug, Task

Suggested Reviewers

  • ApekshaBhosale
  • sagar-qa007
  • rajatagrawal

Poem

🌟 In the realm of code where changes flow,
Caching and tracing, watch them grow!
ETags dancing, responses in flight,
Service workers shining, making it right!
With each line crafted, our app takes its place,
In the world of tech, we quicken the pace! 🚀

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Jan 28, 2025
@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 28, 2025

/build-deploy-preview skip-tests=true

@dvj1988 dvj1988 added the ok-to-test Required label for CI label Jan 28, 2025
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/13009113652.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 38873.
recreate: .

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 28, 2025

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/13009215068.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 38873.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-38873.dp.appsmith.com

@dvj1988 dvj1988 marked this pull request as ready for review January 28, 2025 11:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (8)
app/server/appsmith-server/src/main/resources/application.properties (2)

91-91: Document the New Relic integration setup.

Consider adding a comment above this property to document:

  • The purpose of the New Relic integration
  • Required environment variables
  • Protocol details (gRPC)
+ # New Relic OTLP/gRPC exporter endpoint for distributed tracing
 management.otlp.tracing.endpoint=${APPSMITH_NEW_RELIC_OTEL_EXPORTER_OTLP_ENDPOINT:https://otlp.nr-data.net:4317}/v1/traces

91-91: Review security implications of external OTLP endpoint.

The configuration exposes tracing data to an external endpoint. Ensure:

  1. The endpoint URL is configurable per environment
  2. Proper authentication is in place
  3. Sensitive data is filtered from traces
app/client/src/serviceWorker.ts (2)

12-13: Consider removing unused manifest variable.
If wbManifest is no longer referenced, removing it may simplify the code.


15-16: Handle promise from caches.delete().
Currently, the deletion result is ignored; consider awaiting it or adding a log to confirm cache removal success.

app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java (1)

107-137: ETag logic successfully implemented.
The measured computation time is logged, and conditional checks for If-None-Match appear correct. Keep an eye on potential performance impacts for large response payloads.

app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java (3)

648-702: Consider making ObjectMapper a singleton field for better performance.

The ObjectMapper instance is created for each method call. Consider making it a class-level field to avoid repeated instantiation.

+ private final ObjectMapper objectMapper;

  public ConsolidatedAPIServiceCEImpl(...) {
+     this.objectMapper = new ObjectMapper();
+     this.objectMapper.registerModule(new JavaTimeModule());
  }

  @NotNull public String computeConsolidatedAPIResponseEtag(...) {
-     ObjectMapper objectMapper = new ObjectMapper();
-     objectMapper.registerModule(new JavaTimeModule());

Otherwise, the implementation looks good with proper error handling, strong hashing, and tracing integration.


648-702: Consider enhancing the ETag computation implementation.

While the implementation is functionally correct, consider these improvements:

  1. Extract empty string literals to constants
  2. Use Optional to simplify null checks
  3. Use a Map builder instead of Map.of for better maintainability
+ private static final String EMPTY_ETAG = "";
+ private static final String HASH_ALGORITHM = "SHA-256";

 @NotNull public String computeConsolidatedAPIResponseEtag(
         ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO, String defaultPageId, String applicationId) {
     if (isBlank(defaultPageId) && isBlank(applicationId)) {
-        return "";
+        return EMPTY_ETAG;
     }

     Span computeEtagSpan = observationHelper.createSpan(ETAG_SPAN).start();

     try {
-        String lastDeployedAt = consolidatedAPIResponseDTO.getPages() != null
-                ? consolidatedAPIResponseDTO
-                        .getPages()
-                        .getData()
-                        .getApplication()
-                        .getLastDeployedAt()
-                        .toString()
-                : null;
+        String lastDeployedAt = Optional.ofNullable(consolidatedAPIResponseDTO.getPages())
+                .map(pages -> pages.getData())
+                .map(data -> data.getApplication())
+                .map(app -> app.getLastDeployedAt())
+                .map(Object::toString)
+                .orElse(null);

         if (lastDeployedAt == null) {
-            return "";
+            return EMPTY_ETAG;
         }

-        Object currentTheme = consolidatedAPIResponseDTO.getCurrentTheme() != null
-                ? consolidatedAPIResponseDTO.getCurrentTheme()
-                : "";
-        Object themes = consolidatedAPIResponseDTO.getThemes() != null
-                ? consolidatedAPIResponseDTO.getThemes()
-                : Collections.emptyList();
+        Object currentTheme = Optional.ofNullable(consolidatedAPIResponseDTO.getCurrentTheme())
+                .orElse(EMPTY_ETAG);
+        Object themes = Optional.ofNullable(consolidatedAPIResponseDTO.getThemes())
+                .orElse(Collections.emptyList());

-        Map<String, Object> consolidateAPISignature = Map.of(
-                "userProfile", consolidatedAPIResponseDTO.getUserProfile(),
-                "featureFlags", consolidatedAPIResponseDTO.getFeatureFlags(),
-                "tenantConfig", consolidatedAPIResponseDTO.getTenantConfig(),
-                "productAlert", consolidatedAPIResponseDTO.getProductAlert(),
-                "currentTheme", currentTheme,
-                "themes", themes,
-                "lastDeployedAt", lastDeployedAt);
+        Map<String, Object> consolidateAPISignature = new HashMap<>();
+        consolidateAPISignature.put("userProfile", consolidatedAPIResponseDTO.getUserProfile());
+        consolidateAPISignature.put("featureFlags", consolidatedAPIResponseDTO.getFeatureFlags());
+        consolidateAPISignature.put("tenantConfig", consolidatedAPIResponseDTO.getTenantConfig());
+        consolidateAPISignature.put("productAlert", consolidatedAPIResponseDTO.getProductAlert());
+        consolidateAPISignature.put("currentTheme", currentTheme);
+        consolidateAPISignature.put("themes", themes);
+        consolidateAPISignature.put("lastDeployedAt", lastDeployedAt);

         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.registerModule(new JavaTimeModule());

         String consolidateAPISignatureJSON = objectMapper.writeValueAsString(consolidateAPISignature);

-        MessageDigest digest = MessageDigest.getInstance("SHA-256");
+        MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM);
         byte[] hashBytes = digest.digest(consolidateAPISignatureJSON.getBytes(StandardCharsets.UTF_8));
         String etag = Base64.getEncoder().encodeToString(hashBytes);

         return etag;
     } catch (Exception e) {
         log.error("Error while computing etag for ConsolidatedAPIResponseDTO", e);
-        return "";
+        return EMPTY_ETAG;
     } finally {
         observationHelper.endSpan(computeEtagSpan, true);
     }
 }

648-702: LGTM! Well-implemented ETag computation with proper error handling.

The implementation includes proper validation, error handling, and comprehensive object mapping for ETag computation.

Consider optimizing object creation and string operations.

The current implementation creates new objects for each ETag computation. Consider:

  1. Making the ObjectMapper a static final field
  2. Using a StringBuilder for string concatenation
+    private static final ObjectMapper objectMapper;
+    
+    static {
+        objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+    }

     @NotNull public String computeConsolidatedAPIResponseEtag(
             ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO, String defaultPageId, String applicationId) {
-            ObjectMapper objectMapper = new ObjectMapper();
-            objectMapper.registerModule(new JavaTimeModule());
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d1f515 and f91e4f7.

📒 Files selected for processing (12)
  • app/client/craco.build.config.js (2 hunks)
  • app/client/src/serviceWorker.ts (2 hunks)
  • app/client/start-https.sh (1 hunks)
  • app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java (1 hunks)
  • app/server/appsmith-server/pom.xml (1 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java (4 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java (3 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCE.java (1 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java (6 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java (3 hunks)
  • app/server/appsmith-server/src/main/resources/application.properties (1 hunks)
  • deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs (1 hunks)
👮 Files not reviewed due to content moderation or server errors (2)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java
⏰ Context from checks skipped due to timeout of 90000ms (61)
  • GitHub Check: perform-test / ci-test / ci-test (59)
  • GitHub Check: perform-test / ci-test / ci-test (58)
  • GitHub Check: perform-test / ci-test / ci-test (57)
  • GitHub Check: perform-test / ci-test / ci-test (56)
  • GitHub Check: perform-test / ci-test / ci-test (55)
  • GitHub Check: perform-test / ci-test / ci-test (54)
  • GitHub Check: perform-test / ci-test / ci-test (53)
  • GitHub Check: perform-test / ci-test / ci-test (52)
  • GitHub Check: perform-test / ci-test / ci-test (51)
  • GitHub Check: perform-test / ci-test / ci-test (50)
  • GitHub Check: perform-test / ci-test / ci-test (49)
  • GitHub Check: perform-test / ci-test / ci-test (48)
  • GitHub Check: perform-test / ci-test / ci-test (47)
  • GitHub Check: perform-test / ci-test / ci-test (46)
  • GitHub Check: perform-test / ci-test / ci-test (45)
  • GitHub Check: perform-test / ci-test / ci-test (44)
  • GitHub Check: perform-test / ci-test / ci-test (43)
  • GitHub Check: perform-test / ci-test / ci-test (42)
  • GitHub Check: perform-test / ci-test / ci-test (41)
  • GitHub Check: perform-test / ci-test / ci-test (40)
  • GitHub Check: perform-test / ci-test / ci-test (39)
  • GitHub Check: perform-test / ci-test / ci-test (38)
  • GitHub Check: perform-test / ci-test / ci-test (37)
  • GitHub Check: perform-test / ci-test / ci-test (36)
  • GitHub Check: perform-test / ci-test / ci-test (35)
  • GitHub Check: perform-test / ci-test / ci-test (34)
  • GitHub Check: perform-test / ci-test / ci-test (33)
  • GitHub Check: perform-test / ci-test / ci-test (32)
  • GitHub Check: perform-test / ci-test / ci-test (31)
  • GitHub Check: perform-test / ci-test / ci-test (30)
  • GitHub Check: perform-test / ci-test / ci-test (29)
  • GitHub Check: perform-test / ci-test / ci-test (28)
  • GitHub Check: perform-test / ci-test / ci-test (27)
  • GitHub Check: perform-test / ci-test / ci-test (26)
  • GitHub Check: perform-test / ci-test / ci-test (25)
  • GitHub Check: perform-test / ci-test / ci-test (24)
  • GitHub Check: perform-test / ci-test / ci-test (23)
  • GitHub Check: perform-test / ci-test / ci-test (22)
  • GitHub Check: perform-test / ci-test / ci-test (21)
  • GitHub Check: perform-test / ci-test / ci-test (20)
  • GitHub Check: perform-test / ci-test / ci-test (19)
  • GitHub Check: perform-test / ci-test / ci-test (18)
  • GitHub Check: perform-test / ci-test / ci-test (17)
  • GitHub Check: perform-test / ci-test / ci-test (16)
  • GitHub Check: perform-test / ci-test / ci-test (15)
  • GitHub Check: perform-test / ci-test / ci-test (14)
  • GitHub Check: perform-test / ci-test / ci-test (13)
  • GitHub Check: perform-test / ci-test / ci-test (12)
  • GitHub Check: perform-test / ci-test / ci-test (11)
  • GitHub Check: perform-test / ci-test / ci-test (10)
  • GitHub Check: perform-test / ci-test / ci-test (9)
  • GitHub Check: perform-test / ci-test / ci-test (8)
  • GitHub Check: perform-test / ci-test / ci-test (7)
  • GitHub Check: perform-test / ci-test / ci-test (6)
  • GitHub Check: perform-test / ci-test / ci-test (5)
  • GitHub Check: perform-test / ci-test / ci-test (4)
  • GitHub Check: perform-test / ci-test / ci-test (3)
  • GitHub Check: perform-test / ci-test / ci-test (2)
  • GitHub Check: perform-test / ci-test / ci-test (1)
  • GitHub Check: perform-test / ci-test / ci-test (0)
  • GitHub Check: server-unit-tests / server-unit-tests
🔇 Additional comments (18)
app/client/start-https.sh (2)

298-300: LGTM: Correct approach for preserving ETag.

The gzip compression is correctly disabled to prevent ETag stripping. The provided references explain the technical reasoning behind this decision.


301-304: LGTM: Proper Cache-Control header handling.

The Cache-Control header configuration is correctly implemented:

  1. Clearing the server block's header
  2. Allowing the upstream's header to pass through

This setup allows the backend to have full control over caching behavior.

app/server/appsmith-server/src/main/resources/application.properties (1)

91-91: Verify OTLP protocol compatibility with New Relic endpoint.

The endpoint change from port 4318 to 4317 suggests a switch from OTLP/HTTP to OTLP/gRPC protocol. Ensure that:

  1. The application's OTLP exporter is configured for gRPC
  2. All required gRPC dependencies are included
✅ Verification successful

Protocol compatibility verified for New Relic OTLP endpoint

The OpenTelemetry dependencies (v1.43.0) support both HTTP and gRPC protocols. Spring Boot will automatically use gRPC for port 4317. No additional configuration needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for gRPC dependencies in build files
echo "Checking for gRPC dependencies..."
find . -name "pom.xml" -type f -exec grep -l "grpc" {} \;

Length of output: 135


Script:

#!/bin/bash
# Check for OpenTelemetry dependencies and configuration
echo "Checking OpenTelemetry dependencies..."
find . -name "pom.xml" -type f -exec grep -l "opentelemetry" {} \;

echo -e "\nChecking OTLP exporter configuration in code..."
rg -l "OtlpGrpc|OtlpHttp" --type java

Length of output: 342


Script:

#!/bin/bash
echo "Checking OpenTelemetry dependencies in server pom.xml..."
cat ./app/server/appsmith-server/pom.xml | grep -A 5 -B 5 "opentelemetry"

Length of output: 1130

app/client/src/serviceWorker.ts (1)

1-3: Imports streamlined successfully.
Removing unused imports and keeping only the NetworkOnly strategy looks consistent with the new caching approach.

app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java (2)

14-16: Imports look good.
New imports for ETag logic and changed return types appear appropriate.

Also applies to: 19-19, 30-30


85-91: Method signature updated to support 304 responses.
Switching from Mono<ResponseDTO> to Mono<ResponseEntity<ResponseDTO>> plus if-none-match header handling is a clean way to implement conditional requests.

app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCE.java (1)

13-14: New ETag computation method is well-placed.
Adding a dedicated interface method clarifies responsibilities and facilitates testing.

app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java (1)

34-34: LGTM! The span constant follows the established pattern.

The new ETAG_SPAN constant correctly follows the naming convention and will be properly tracked as it starts with the required "appsmith." prefix.

app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java (1)

39-40: LGTM! Clean dependency injection implementation.

The ObservationHelper is properly injected and passed to the superclass, maintaining the established dependency injection pattern.

Also applies to: 58-59

app/client/craco.build.config.js (1)

17-17: Verify the performance impact of disabling service worker caching.

The changes disable service worker caching for all static assets (JS, CSS, HTML, images). While this aligns with moving to ETag-based caching, verify that:

  1. The browser's HTTP cache is properly configured for these assets
  2. The performance impact is acceptable, especially for repeat visitors

Also applies to: 34-34

✅ Verification successful

Service worker caching changes are well-compensated

The build configuration shows appropriate compensating controls:

  • Brotli compression for efficient transfer
  • Chunk retry mechanism for reliability
  • Browser's default caching behavior remains unaffected
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check HTTP cache headers for static assets
echo "Checking cache headers for static assets..."
curl -I -H "Accept-Encoding: gzip" http://localhost/static/js/main.js 2>/dev/null | grep -i "cache-control\|etag"
curl -I -H "Accept-Encoding: gzip" http://localhost/static/css/main.css 2>/dev/null | grep -i "cache-control\|etag"

Length of output: 306


Script:

#!/bin/bash
# Check for server-side caching configuration
echo "Searching for caching middleware and ETag configuration..."
rg -l "etag|cache-control" --type js

# Check for specific caching middleware
echo -e "\nChecking for common caching middleware..."
rg -l "express\.static|compression|helmet" --type js

# Look for custom caching implementation
echo -e "\nChecking for custom caching implementation..."
ast-grep --pattern 'app.use($$$cache$$$)'

Length of output: 503


Script:

#!/bin/bash
# Check build config content
echo "Examining build configuration..."
cat app/client/craco.build.config.js

# Look for server configuration files
echo -e "\nSearching for server configuration files..."
fd -e js -e ts server.js server.ts index.js index.ts

Length of output: 4116

deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs (1)

133-140: LGTM! Proper reverse proxy configuration for ETag support.

The route handler is correctly configured to:

  1. Forward requests to the backend
  2. Pass the ETag header from the response
  3. Maintain security headers and request tracking
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java (4)

5-5: LGTM! Appropriate imports and field additions for ETag functionality.

The new imports and ObservationHelper field support the ETag computation and tracing requirements.

Also applies to: 36-37, 54-55, 57-57, 76-76, 119-119


677-685: LGTM! Comprehensive field selection for ETag computation.

The selected fields appropriately cover all the essential data that would affect the response content, ensuring proper cache validation.


5-5: LGTM! Appropriate imports and field addition for ETag support.

The new imports and ObservationHelper field are well-aligned with the ETag computation requirements.

Also applies to: 36-37, 54-55, 57-57, 119-119


5-5: LGTM! Clean addition of required dependencies.

The new imports and ObservationHelper field are well-organized and necessary for the ETag computation functionality.

Also applies to: 36-37, 54-55, 57-57, 119-119

app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java (3)

42-43: LGTM! Proper constructor parameter addition.

The ObservationHelper parameter is correctly added and passed to the super constructor.

Also applies to: 61-62


42-43: LGTM! Constructor parameter addition is correct.

The ObservationHelper parameter is properly added and passed to the super constructor.

Also applies to: 61-62


42-43: LGTM! Clean constructor update.

The ObservationHelper parameter is properly added and passed to the super constructor.

Also applies to: 61-62

Comment on lines +415 to +419
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.17.0</version>
</dependency>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Use property reference for jackson-datatype-jsr310 version

The version should reference the property ${jackson-bom.version} instead of hard-coding it, maintaining consistency with other Jackson dependencies in the project.

 <dependency>
     <groupId>com.fasterxml.jackson.datatype</groupId>
     <artifactId>jackson-datatype-jsr310</artifactId>
-    <version>2.17.0</version>
+    <version>${jackson-bom.version}</version>
 </dependency>
🔗 Analysis chain

Verify jackson-datatype-jsr310 version and management

The addition of this dependency is appropriate for handling Java 8 date/time types in the ETag implementation. However, there are a few considerations:

  1. Version 2.17.0 needs verification as it appears to be a future version
  2. The version should ideally be managed through the properties section for better maintenance

Run this script to check the latest stable version and current usage:

Consider managing the version in properties:

 <properties>
     <jmh.version>1.35</jmh.version>
     <org.modelmapper.version>2.4.4</org.modelmapper.version>
+    <jackson.version>2.17.0</jackson.version>
 </properties>

 <dependency>
     <groupId>com.fasterxml.jackson.datatype</groupId>
     <artifactId>jackson-datatype-jsr310</artifactId>
-    <version>2.17.0</version>
+    <version>${jackson.version}</version>
 </dependency>
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check latest version from Maven Central
curl -s "https://search.maven.org/solrsearch/select?q=g:com.fasterxml.jackson.datatype+AND+a:jackson-datatype-jsr310&rows=1&wt=json" | jq -r '.response.docs[0].latestVersion'

# Check if version is already managed by Spring Boot
rg "jackson.*version" -g "pom.xml"

Length of output: 3399

@dvj1988 dvj1988 requested a review from rajatagrawal January 28, 2025 12:32
@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13027414986.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 0 Total Failed: 2 Total Skipped: 0 *****************************

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1 specs_to_run=cypress/e2e/Regression/ClientSide/ExplorerTests/Page_Load_Spec.js

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13028801688.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 1 Total Failed: 1 Total Skipped: 0 *****************************

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1 specs_to_run=cypress/e2e/Regression/ClientSide/ExplorerTests/Page_Load_Spec.js

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13029270459.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 0 Total Failed: 1 Total Skipped: 1 *****************************

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1 specs_to_run=cypress/e2e/Regression/ClientSide/ExplorerTests/Page_Load_Spec.js update_snapshot=true

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13030032295.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 0 Total Failed: 1 Total Skipped: 1 *****************************

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1 specs_to_run=cypress/e2e/Regression/ClientSide/ExplorerTests/Page_Load_Spec.js update_snapshot=true

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13030403281.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 0 Total Failed: 1 Total Skipped: 1 *****************************

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 29, 2025

/ci-test-limit-count run_count=1 specs_to_run=cypress/e2e/Regression/ClientSide/ExplorerTests/Page_Load_Spec.js

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13033582521.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 2 Total Passed: 0 Total Failed: 2 Total Skipped: 0 *****************************

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 812a10c and c63507d.

📒 Files selected for processing (1)
  • app/client/cypress/support/Pages/AggregateHelper.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/client/cypress/support/Pages/AggregateHelper.ts (1)

Pattern app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:

  • Follow best practices for Cypress code and e2e automation.
  • Avoid using cy.wait in code.
  • Avoid using cy.pause in code.
  • Avoid using agHelper.sleep().
  • Use locator variables for locators and do not use plain strings.
  • Use data-* attributes for selectors.
  • Avoid Xpaths, Attributes and CSS path.
  • Avoid selectors like .btn.submit or button[type=submit].
  • Perform logins via API with LoginFromAPI.
  • Perform logout via API with LogOutviaAPI.
  • Perform signup via API with SignupFromAPI.
  • Avoid using it.only.
  • Avoid using after and aftereach in test cases.
  • Use multiple assertions for expect statements.
  • Avoid using strings for assertions.
  • Do not use duplicate filenames even with different paths.
  • Avoid using agHelper.Sleep, this.Sleep in any file in code.
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-build / client-build
  • GitHub Check: server-unit-tests / server-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: server-spotless / spotless-check
  • GitHub Check: client-prettier / prettier-check

@@ -1193,7 +1193,7 @@ export class AggregateHelper {
this.locator._specificToast("Cannot read properties of undefined"),
);
this.assertHelper.AssertDocumentReady();
this.Sleep(4000); //for page to load for CI runs
cy.wait(4000); //for page to load for CI runs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace cy.wait with proper wait conditions.

The use of cy.wait(4000) violates the coding guidelines which state "Avoid using cy.wait in code". Fixed wait times are unreliable and can lead to flaky tests.

Consider this alternative implementation that uses proper wait conditions:

-    cy.wait(4000); //for page to load for CI runs
+    // Wait for page load indicators
+    this.AssertElementAbsence(this.locator._loading);
+    this.AssertElementAbsence(this.locator._animationSpnner);
+    this.assertHelper.AssertDocumentReady();

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
app/client/cypress/support/Objects/FeatureFlags.ts (2)

35-35: LGTM! Consider using undefined assignment for better performance.

The header deletion ensures tests always get fresh responses, which is correct for testing Etag implementation.

-    delete req.headers["if-none-match"];
+    req.headers["if-none-match"] = undefined;
🧰 Tools
🪛 Biome (1.9.4)

[error] 35-35: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


90-90: LGTM! Consider using undefined assignment for consistency.

The header deletion ensures consistent behavior with the previous interceptor.

-      delete req.headers["if-none-match"];
+      req.headers["if-none-match"] = undefined;
🧰 Tools
🪛 Biome (1.9.4)

[error] 90-90: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c63507d and 6ad4395.

📒 Files selected for processing (1)
  • app/client/cypress/support/Objects/FeatureFlags.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/client/cypress/support/Objects/FeatureFlags.ts (1)

Pattern app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:

  • Follow best practices for Cypress code and e2e automation.
  • Avoid using cy.wait in code.
  • Avoid using cy.pause in code.
  • Avoid using agHelper.sleep().
  • Use locator variables for locators and do not use plain strings.
  • Use data-* attributes for selectors.
  • Avoid Xpaths, Attributes and CSS path.
  • Avoid selectors like .btn.submit or button[type=submit].
  • Perform logins via API with LoginFromAPI.
  • Perform logout via API with LogOutviaAPI.
  • Perform signup via API with SignupFromAPI.
  • Avoid using it.only.
  • Avoid using after and aftereach in test cases.
  • Use multiple assertions for expect statements.
  • Avoid using strings for assertions.
  • Do not use duplicate filenames even with different paths.
  • Avoid using agHelper.Sleep, this.Sleep in any file in code.
🪛 Biome (1.9.4)
app/client/cypress/support/Objects/FeatureFlags.ts

[error] 35-35: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 90-90: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
  • GitHub Check: server-unit-tests / server-unit-tests
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: server-spotless / spotless-check
  • GitHub Check: client-prettier / prettier-check

@dvj1988
Copy link
Contributor Author

dvj1988 commented Jan 30, 2025

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/13046455111.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 38873.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-38873.dp.appsmith.com

@dvj1988 dvj1988 merged commit 01cda23 into release Jan 30, 2025
83 checks passed
@dvj1988 dvj1988 deleted the chore/cache-consolidated-api branch January 30, 2025 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants