LIGHT

  • News
  • Docs
  • Community
  • Reddit
  • GitHub
Star

Data Structure Change

While working on the light-portal, I sometimes needed to change the data structure or schema for an endpoint. As the portal application has too many moving parts, I am using this document to collect all the necessary changes in each repository and project as a reminder. It can be a guide for new developers in the future.

The change for today is to remove the email from the change password endpoint. We don’t need to have an additional email field in the form because only a logged-in user can take action. The email can be retrieved from the JWT token on the server.

model-config

Let’s make the change from the service schema first. The user-command service schema is located in the model-config for the project generation.

steve@freedom:~/networknt/model-config$ git diff hybrid/user-command/schema.json
diff --git a/hybrid/user-command/schema.json b/hybrid/user-command/schema.json
index 898a1dc..3984f87 100644
--- a/hybrid/user-command/schema.json
+++ b/hybrid/user-command/schema.json
@@ -205,10 +205,6 @@
         "title": "Service",
         "type": "object",
         "properties": {
-          "email": {
-            "type": "string",
-            "description": "email address of the user"
-          },
           "oldPassword": {
             "type": "string",
             "description": "the old password"
@@ -223,7 +219,6 @@
           }
         },
         "required": [
-          "email",
           "oldPassword",
           "newPassword",
           "passwordConfirm"

In the JSON schema, we remove the email field and email from the required.

Here is the issue that is tracking the change.

portal-event

This is a component that contains all the Avro schemas and generated Java code. The user-command service will convert the input into an event in Avro format and send it to Kafka so that user-query can get the streams to process it. The change is something like below.

steve@freedom:~/networknt/light-portal$ git diff portal-event/src/main/avro/PasswordChangedEvent.avsc
diff --git a/portal-event/src/main/avro/PasswordChangedEvent.avsc b/portal-event/src/main/avro/PasswordChangedEvent.avsc
index f1096c0..bef1a21 100644
--- a/portal-event/src/main/avro/PasswordChangedEvent.avsc
+++ b/portal-event/src/main/avro/PasswordChangedEvent.avsc
@@ -22,11 +22,6 @@
           }
         ]
       }
-    },
-     {
-      "name": "email",
-      "type": "string",
-      "doc": "email of the user to be deleted"
     },
     {
       "name": "password",

After the Avro schema file is changed, we need to compile it to generate the Java code. Please use the following commands to do that.

cd ~/networknt/light-portal/portal-event/src/main/avro
./compile.sh

To compile the generated code, we run the maven command.

cd ~/networknt/light-portal/portal-event
mvn clean install

Here is an issue that is tracking the change.

user-command

The service user-command is the one to handle the changePassword endpoint. It was generated from the schema in the model-config above. To make it simple, we are not going to regenerate the project again, just make the change in the schema file like below.

steve@freedom:~/networknt/light-portal/user-command$ git diff src/main/resources/schema.json
diff --git a/user-command/src/main/resources/schema.json b/user-command/src/main/resources/schema.json
index 5d5a912..592dd7f 100644
--- a/user-command/src/main/resources/schema.json
+++ b/user-command/src/main/resources/schema.json
@@ -19,10 +19,6 @@
       "title": "Service",
       "type": "object",
       "properties": {
-        "email": {
-          "type": "string",
-          "pattern": "^\\S+@\\S+$"
-        },
         "oldPassword": {
           "type": "string",
           "description": "the old password"
@@ -37,7 +33,6 @@
         }
       },
       "required": [
-        "email",
         "oldPassword",
         "newPassword",
         "passwordConfirm"

Here is the issue that is tracking the change.

Of course, we need to change the ChangePassword.java in the handler folder to remove the email from the input. The detailed change in Java code is combined with others and can be viewed in this issue.

user-query

The user-query service has a stream processor that handles all the events. We need to double-check the PasswordChangedEvent logic. Here is the changes we have made to the UserQueryStreams.java

steve@freedom:~/networknt/light-portal/user-query$ git diff src/main/java/net/lightapi/portal/user/query/UserQueryStreams.java
diff --git a/user-query/src/main/java/net/lightapi/portal/user/query/UserQueryStreams.java b/user-query/src/main/java/net/lightapi/portal/user/query/UserQueryStreams.java
index 5218d3a..b870a50 100644
--- a/user-query/src/main/java/net/lightapi/portal/user/query/UserQueryStreams.java
+++ b/user-query/src/main/java/net/lightapi/portal/user/query/UserQueryStreams.java
@@ -306,9 +306,8 @@ public class UserQueryStreams implements LightStreams {
                 // make sure that we have user available.
                 PasswordChangedEvent passwordChangedEvent = (PasswordChangedEvent)object;
                 if(logger.isTraceEnabled()) logger.trace("Event = " + passwordChangedEvent);
-                String id = passwordChangedEvent.getEventId().getId();
+                String email = passwordChangedEvent.getEventId().getId();
                 long nonce = passwordChangedEvent.getEventId().getNonce();
-                String email = passwordChangedEvent.getEmail();
                 String password = passwordChangedEvent.getPassword();
                 String oldPassword = passwordChangedEvent.getOldPassword();
                 String storedPassword = passwordStore.get(email);
@@ -326,7 +325,7 @@ public class UserQueryStreams implements LightStreams {
                     addNotification(email, new EventNotification(nonce, false, "Failed to validate the old password.", AvroConverter.toJson(passwordChangedEvent, false)));
                     return;
                 }
-                nonceStore.put(id, nonce + 1);
+                nonceStore.put(email, nonce + 1);
                 addNotification(email, new EventNotification(nonce, true, null, AvroConverter.toJson(passwordChangedEvent, false)));
             } else if(object instanceof UserDeletedEvent) {
                 // make sure that we have user available.

Here is the issue that is tracking the change.

view

The last step is to update the form definition in the portal view project for the UI. We don’t have the form defined yet, so we add a new form in the Form.json file.

steve@freedom:~/networknt/light-portal$ git diff view/src/data/Forms.json
diff --git a/view/src/data/Forms.json b/view/src/data/Forms.json
index dd8a479..9765c6b 100644
--- a/view/src/data/Forms.json
+++ b/view/src/data/Forms.json
@@ -167,6 +167,52 @@
       "address"
     ]
   },
+  "changePasswordForm": {
+    "formId": "changePasswordForm",
+    "actions": [
+      {
+        "host": "lightapi.net",
+        "title": "Change Password",
+        "success": "/#/app/success",
+        "failure": "/#/app/failure"
+      }
+    ],
+    "schema": {
+      "title": "Change Password",
+      "type": "object",
+      "properties": {
+        "oldPassword": {
+          "type": "string"
+        },
+        "newPassword": {
+          "type": "string"
+        },
+        "passwordConfirm": {
+          "type": "string"
+        }
+      },  
+      "required": [
+        "oldPassword",
+        "newPassword",
+        "passwordConfirm"
+      ]
+    },
+    "form": [
+      {
+        "key": "oldPassword",
+        "type": "password"
+      },
+      {
+        "key": "newPassword",
+        "type": "password"
+      },
+      {
+        "key": "passwordConfirm",
+        "type": "password"
+      }
+    ]
+  },
+
   "service": {
     "schema": {
       "type": "object",

Here is the issue that is tracking the change.

Summary

As you can see, changing the data structure in the light-portal is not an easy job. There are so many places that need to be touched; however, the changes are relatively easy to understand.

If you need another example, please take a look at this issue.

To ease the pain to change the JSON schema in model-config, user-command, and view, we are going to develop a JSON schema market place in the light-portal so that we can only change one location and all three are using a remote reference.

  • About Light
    • Overview
    • Testimonials
    • What is Light
    • Features
    • Principles
    • Benefits
    • Roadmap
    • Community
    • Articles
    • Videos
    • License
    • Why Light Platform
  • Getting Started
    • Get Started Overview
    • Environment
    • Light Codegen Tool
    • Light Rest 4j
    • Light Tram 4j
    • Light Graphql 4j
    • Light Hybrid 4j
    • Light Eventuate 4j
    • Light Oauth2
    • Light Portal Service
    • Light Proxy Server
    • Light Router Server
    • Light Config Server
    • Light Saga 4j
    • Light Session 4j
    • Webserver
    • Websocket
    • Spring Boot Servlet
  • Architecture
    • Architecture Overview
    • API Category
    • API Gateway
    • Architecture Patterns
    • CQRS
    • Eco System
    • Event Sourcing
    • Fail Fast vs Fail Slow
    • Integration Patterns
    • JavaEE declining
    • Key Distribution
    • Microservices Architecture
    • Microservices Monitoring
    • Microservices Security
    • Microservices Traceability
    • Modular Monolith
    • Platform Ecosystem
    • Plugin Architecture
    • Scalability and Performance
    • Serverless
    • Service Collaboration
    • Service Mesh
    • SOA
    • Spring is bloated
    • Stages of API Adoption
    • Transaction Management
    • Microservices Cross-cutting Concerns Options
    • Service Mesh Plus
    • Service Discovery
  • Design
    • Design Overview
    • Design First vs Code First
    • Desgin Pattern
    • Service Evolution
    • Consumer Contract and Consumer Driven Contract
    • Handling Partial Failure
    • Idempotency
    • Server Life Cycle
    • Environment Segregation
    • Database
    • Decomposition Patterns
    • Http2
    • Test Driven
    • Multi-Tenancy
    • Why check token expiration
    • WebServices to Microservices
  • Cross-Cutting Concerns
    • Concerns Overview
  • API Styles
    • Light-4j for absolute performance
    • Style Overview
    • Distributed session on IMDG
    • Hybrid Serverless Modularized Monolithic
    • Kafka - Event Sourcing and CQRS
    • REST - Representational state transfer
    • Web Server with Light
    • Websocket with Light
    • Spring Boot Integration
    • Single Page Application
    • GraphQL - A query language for your API
    • Light IBM MQ
    • Light AWS Lambda
    • Chaos Monkey
  • Infrastructure Services
    • Service Overview
    • Light Proxy
    • Light Mesh
    • Light Router
    • Light Portal
    • Messaging Infrastructure
    • Centralized Logging
    • COVID-19
    • Light OAuth2
    • Metrics and Alerts
    • Config Server
    • Tokenization
    • Light Controller
  • Tool Chain
    • Tool Chain Overview
  • Utility Library
  • Service Consumer
    • Service Consumer
  • Development
    • Development Overview
  • Deployment
    • Deployment Overview
    • Frontend Backend
    • Linux Service
    • Windows Service
    • Install Eventuate on Windows
    • Secure API
    • Client vs light-router
    • Memory Limit
    • Deploy to Kubernetes
  • Benchmark
    • Benchmark Overview
  • Tutorial
    • Tutorial Overview
  • Troubleshooting
    • Troubleshoot
  • FAQ
    • FAQ Overview
  • Milestones
  • Contribute
    • Contribute to Light
    • Development
    • Documentation
    • Example
    • Tutorial
“Data Structure Change” was last updated: July 5, 2021: fixes #275 checked and corrected grammar/spelling for majority of pages (#276) (b3bbb7b)
Improve this page
  • News
  • Docs
  • Community
  • Reddit
  • GitHub
  • About Light
  • Getting Started
  • Architecture
  • Design
  • Cross-Cutting Concerns
  • API Styles
  • Infrastructure Services
  • Tool Chain
  • Utility Library
  • Service Consumer
  • Development
  • Deployment
  • Benchmark
  • Tutorial
  • Troubleshooting
  • FAQ
  • Milestones
  • Contribute