Loading Audio...

Listen to Lesson
0:00
  • Speed 0.5x
  • Speed 0.75x
  • Speed 1x
  • Speed 1.25x
  • Speed 1.5x
  • Speed 2x
  • Brian
  • Caris

Adding Custom Business Logic to Clarity's Distributor Management App

Clarity’s distributor management app requires automation to manage workflow states and execute actions. You’ve already imported Clarity’s object model for this application. Decoupling the application is critical for maximizing performance when handling complex functionalities and business logic.

Now, it’s time to implement a microservice client extension to offload account creation for Clarity’s approved distributor applications.

Exercise: Configuring the Microservice Client Extension

Here, you'll set up the structure for Clarity's microservice client extension handling distributor management actions.

  1. Open a file explorer and navigate to the client-extensions/ folder in your course workspace.

  2. Create a new folder named clarity-distributor-mgmt-action.
    You'll use this folder to consolidate the microservice actions for Clarity's distributor management app.

    NOTE
    It's considered best practice to group all the components for a specific application within a single client extension project.
  3. From the exercises/module-2/liferay-sample-etc-spring-boot/ folder, move these files to the clarity-distributor-mgmt-action/ folder:

    • build.gradle
    • Dockerfile
    • LCP.json

    Now that you've included the basic configuration files for a client extension project leveraging Spring Boot, you can create the client-extension.yaml file.

  4. Within the clarity-distributor-mgmt-action/ folder, create a new file named client-extension.yaml.

  5. Open the file with a text editor or IDE.

  6. Add this YAML snippet:

    assemble:
        - fromTask: bootJar
    

    This assemble block configures the build process to trigger the bootJar task and include its output (a .jar file) in the resulting LUFFA.

  7. Insert a new line in the client-extension.yaml and add this YAML snippet:

    clarity-distributor-mgmt-action-oauth-application-user-agent:
        .serviceAddress: localhost:58081
        .serviceScheme: http
        name: Clarity Distributor Mgmt Action OAuth Application User Agent
        scopes:
            - Liferay.Headless.Admin.User.everything
        type: oAuthApplicationUserAgent
    

    This definition block configures an OAuth headless user agent configuration client extension, specifying its name and required scope. This secures communication between the microservice and Liferay DXP.

    NOTE
    Including the Liferay.Headless.Admin.User.everything scope is crucial for the client extension to create new accounts for approved distributor users.
  8. Insert a new line and add this YAML snippet:

    clarity-distributor-mgmt-create-account-action:
        name: Clarity Distributor Mgmt Create Account Action
        oAuth2ApplicationExternalReferenceCode: clarity-distributor-mgmt-action-oauth-application-user-agent
        resourcePath: /object/action/account
        type: objectAction
    
  9. Save the file.

Great! Now that you've configured the microservice client extension, you'll include the source code for the distributor management app's business logic.

Exercise: Including Clarity's Business Logic in the Client Extension

Here, you'll start creating the source code that includes the business logic for Clarity's distributor management app.

  1. Within the client-extensions/clarity-distributor-mgmt-action/ folder of the course workspace, create these three folders:

    • src/
    • src/main/
    • src/main/resources/
  2. From the exercises/module-2/liferay-sample-etc-spring-boot/src/main/resources/ folder, move these files into the clarity-distributor-mgmt-action/src/main/resources/ folder:

    • application.properties
    • application-default.properties
  3. Open the application.properties file with a text editor or IDE, and examine its contents.
    For this client extension, you'll leverage the spring.config.import property. This adds additional property files (including the application-default.properties file) and marks specific files as optional, enabling environment-specific configurations.

  4. Open the application-default.properties file, and examine its contents.

    NOTE
    The current content of this file is from the Liferay Sample Workspace. Next, you'll need to update the liferay.oauth.application.external.reference.codes property with the client extension's OAuth 2.0 application reference.
  5. For the liferay.oauth.application.external.reference.codes property, delete the existing reference codes.

  6. Configure the property with the value clarity-distributor-mgmt-action-oauth-application-user-agent.
    Your file should resemble this:

    [...]
    #
    # OAuth
    #
    
    liferay.oauth.application.external.reference.codes=clarity-distributor-mgmt-action-oauth-application-user-agent
    
    liferay.oauth.urls.excludes=/ready
    [...]
    
  7. Save the file.

  8. In clarity-distributor-mgmt-action/src/main/, create these folders for the Java source files:

    • java/
    • java/com/
    • java/com/clarityvisionsolutions/
    • java/com/clarityvisionsolutions/distributor/
    • java/com/clarityvisionsolutions/distributor/mgmt
    • java/com/clarityvisionsolutions/distributor/mgmt/actions/
  9. Navigate to the clarity-distributor-mgmt-action/src/main/java/com/clarityvisionsolutions/distributor/mgmt/actions/ folder and create three new files:

    • ClaritySpringBootApplication.java
    • ReadyRestController.java
    • ObjectActionAccountRestController.java
  10. Open the ClaritySpringBootApplication.java file with a text editor or IDE, and add this code snippet:

    package com.clarityvisionsolutions.distributor.mgmt.actions;
    
    import com.liferay.client.extension.util.spring.boot.ClientExtensionUtilSpringBootComponentScan;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Import;
    
    @Import(ClientExtensionUtilSpringBootComponentScan.class)
    @SpringBootApplication
    public class ClaritySpringBootApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ClaritySpringBootApplication.class, args);
    	}
    
    }
    

    This is a reusable, boilerplate piece of code that annotates the current Java class as a Spring Boot application and imports a Liferay provided class.

  11. Save the file.

  12. Open the ReadyRestController.java file with a text editor or IDE, and add this code snippet:

    package com.clarityvisionsolutions.distributor.mgmt.actions;
    
    import com.liferay.client.extension.util.spring.boot.BaseRestController;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RequestMapping("/ready")
    @RestController
    public class ReadyRestController extends BaseRestController {
    
        @GetMapping
        public String get() {
            return "READY";
        }
    
    }
    

    This Java class is a boilerplate Spring Boot controller that checks if a service is running and ready to accept requests.

  13. Save the file.

  14. Open the ObjectActionAccountRestController.java file with a text editor or IDE, and add this code snippet:

    package com.clarityvisionsolutions.distributor.mgmt.actions;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.core.annotation.AuthenticationPrincipal;
    import org.springframework.security.oauth2.jwt.Jwt;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RequestMapping("/object/action/account")
    @RestController
    public class ObjectActionAccountRestController extends BaseRestController {
    
        @Autowired
        public ObjectActionAccountRestController(
                AccountCreationRequestQueueManager queueManager) {
    
            _queueManager = queueManager;
        }
    
        /**
         * Invoked when a Distributor Application is approved and an Account
         * needs to be created.
         *
         * @param jwt  the JWT token
         * @param json the user creation request in JSON format
         * @return the response entity
         * @throws Exception if an error occurs
         */
        @PostMapping
        public ResponseEntity<String> post(
                @AuthenticationPrincipal Jwt jwt, @RequestBody String json)
                throws Exception {
    
            log(jwt, _log, json);
    
            // Create the request instance
    
            AccountCreationRequest request = new AccountCreationRequest(json, jwt);
    
            // Enqueue the request
    
            _queueManager.enqueue(request);
    
            // Return a success response
    
            return new ResponseEntity<>(json, HttpStatus.OK);
        }
    
        private static final Log _log = LogFactory.getLog(
                ObjectActionAccountRestController.class);
    
        private final AccountCreationRequestQueueManager _queueManager;
    
    }
    

    This code follows an asynchronous approach for handling business logic for objects. It queues the object action's request, handles it in a different thread named _queueManager, and sends a response back to Liferay.

    NOTE
    By not blocking the initial request and instead handling it asynchronously, you ensure performance is not compromised if the object action's logic is slow.
  15. Save the file.

  16. From the exercises/module-2/action-classes/ folder, move these files into the client-extension/clarity-distributor-mgmt-action/src/main/java/com/clarityvisionsolutions/distributor/mgmt/actions folder:

    • TaskExecutorConfig.java
    • AccountCreationRequest.java
    • AccountCreationRequestProcessorService.java
    • AccountCreationRequestQueueManager.java
    • BaseRestController.java
    NOTE
    These files contain the required resources for the object action to perform the asynchronous logic. This code leverages standard Spring Framework classes and libraries that are outside the scope of this course. To learn more, see the official Spring Framework documentation.

    Now that you've fully configured and populated the microservice client extension, you can deploy it to your Liferay instance.

  17. Open a terminal and navigate to the client-extensions/clarity-distributor-mgmt-action/ folder in your course workspace.

  18. Run this command to build and deploy the client extension:

    blade gw clean deploy
    
  19. Verify it deploys successfully.

    INFO [fileinstall-directory-watcher][BundleStartStopLogger:68] STARTED claritydistributormgmtaction_7.4.13 [1464]
    

With your client extension deployed, you can use it when adding object actions.

Exercise: Adding the Set Up Account Action

Here, you'll add an action to the Distributor Application object that uses the microservice client extension you deployed in the previous exercise. Then you’ll start the Spring Boot server.

NOTE
You must create the object action before starting the Spring Boot server.
  1. In your Liferay instance, open the Global Menu (Global Menu), go to the Control Panel tab, and click Objects.

  2. Click the Distributor Application object.

  3. Go to the Actions tab and click Add (Add Button).

  4. Enter these values in the Basic Info tab:

    Field Value
    Action Label Set Up Account
    Action Name setUpAccount
    Description Create a business account for an approved application.
    Active Yes
  5. Go to the Action Builder tab and set these values:

    Field Value
    Trigger Standalone
    Action object-action-executor[function#clarity-distributor-mgmt-action-object-action-account]
    Error Message > Message Failed to set up the business account.
  6. Click Save.
    Now that you've created the Set Up Account object action, you can execute it to automatically create distributor accounts.

  7. Run this command from the client-extensions/clarity-distributor-mgmt-action/ folder to start the Spring Boot service:

    blade gw bootRun
    
  8. When the application starts, go to http://localhost:58081/ready. If the application is ready for use, the page displays “READY”.

Now you can test out the object action.

Exercise: Testing the Object Action

Here you'll create a new distributor application and execute the object action to create a new account.

  1. In your Liferay instance, open the Global Menu (Global Menu), go to the Applications tab, and click Distributor Applications.

  2. Click Add (Add Button) to start creating a new application.

  3. Fill out the fields with these values:

    Field Value
    Applicant Name Richard Howard
    Applicant Email Address richard.howard@howardsvision.com
    Business Name Howard's Vision
    Business Website URL https://www.howardsvision.com
    Business Phone Number 555-867-5309
    Business Tax ID Number 7618231
    Application State Open
  4. Click Save.

  5. Go back to the Distributor Applications menu.

  6. Click Actions (Actions Button) for the entry you created and select Set Up Account.
    Once triggered, the object action will call the Spring Boot application and execute the asynchronous logic you implemented earlier.

  7. Check the terminal window where you executed the bootRun command and see the Spring Boot application's response.

  8. In you Liferay instance, open the Global Menu (Global Menu), go to the Control Panel tab, and click Accounts.

  9. Verify that the Howard's Vision account was created.

  10. Select Howard’s Vision, go to the Users tab, and verify the applicant was associated with the account and assigned the Account Administrator role.

Conclusion

Congratulations! You've added custom business logic to Clarity's distributor management app, offloading account creation to a microservice. By leveraging this microservice client extension, Clarity's environment is better equipped to maximize performance when handling complex functionalities.

Next, you'll review what you've learned before moving on to the next module.

loading-knowledge-label