Exercise: Developing a Multi-Target Application

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Develop a multi-target application project using the SAP Business Application Studio

Developing a Multi-Target Application

Description

Create a simple Node.js project and a simple Java project. Pack them in a unique MTA. Include some simple environment variables. Build and deploy the application to Cloud Foundry.

Prerequisites

For the complete execution of current exercise, you must execute the following other exercise first:

Creating your Pay-As-You-Go Account in SAP BTP

As development environment, this exercise uses the SAP Business Application Studio. In case the studio is not available for any reason, you can execute the same steps locally, using Visual Studio Code. This will require minimal intuitive differences in the environment usage, and no difference in the source code.

Information for execution

The exercise comes with an archive file:

mta-intro-solution.zip[download] contains the MTA project in its final status after the correct execution of the exercise. This project can be used to clarify the correct solution or to copy and paste parts of the source code.

In the case you wish to build and deploy the application to Cloud Foundry directly without going through the exercise steps, then complete the following actions (this is not a prerequisite to exercise execution):

  1. Extract the archive to a workspace in the SAP Business Application Studio.
  2. Open a terminal window and change the directory to the project root folder.
  3. Execute the following sequence of commands:
    Code snippet
    mbt build
    cf login
    cf deploy mta_archives/mta-intro_0.0.1.mtar
    Copy code

Task 1: Create the MTA Project and Modules

Steps

  1. Open the SAP Business Application Studio, open the training development space.

    1. In your Web browser (for example, Google Chrome), open your SAP BTP Cockpit based on the link you received at subscription time (for example: https://cockpit.eu20.hana.ondemand.com). If requested, enter your user and password.

    2. Choose the training subaccount, that you created in a previous exercise.

    3. Choose ServicesInstances and Subscriptions.

    4. Choose SAP Business Application Studio.

    5. Eventually start the training development space.

    6. Once the space is running, click on training to enter the development space.

  2. In the projects folder, create a sub-folder called mta-intro. Open it as a current workspace.

    1. Choose FileOpen Workspace... (Ctrl+Alt+W), choose the projects folder and choose Open.

    2. In the projects folder, create a sub-folder called mta-intro.

    3. Choose FileOpen Workspace... (Ctrl+Alt+W), choose the projects/mta-intro folder and choose Open.

  3. In the mta-intro folder, create a sub-folder called app1. Upload the Node.js application (Hello Node!) provided in the mta-intro-js-hello.zip file [download]. Review and run the application in the studio.

    1. In the mta-intro folder, create a sub-folder called app1.

    2. Drag the mta-intro-js-hello.zip file [download] from its original folder (in Windows) and drop it on the app1 folder in the Studio.

    3. Right-click on the app1 folder, choose Open in Terminal

    4. In the terminal execute the following commands:

      Code snippet
      unzip *.zip
      rm *.zip
      Copy code
    5. Open the main.js file. Review the simple Node.js code.

    6. Open the package.json file. Click on the > Debug control just before the scripts definition and execute the start:debug script.

    7. Once the application has started, a pop up window appears stating A service is listening to port 3002. Choose Open in New Tab. A new tab is opened showing Hello Node!.

    8. Return to the Studio. Choose Stop multiple times until the debugger stops.

    9. Close the JavaScript Debug Terminal window.

  4. In the Web browser, access the https://start.spring.io website, then generate and download a Spring Boot application based on the following information:

    SettingValue
    ProjectMaven Project
    LanguageJava
    Spring Bootleave the default (currently 2.6.4)
    Project Metadataleave the defaults
    PackagingWar
    Java8
    DependenciesSpring Web
    1. In your Web browser, open https://start.spring.io.

    2. Choose the settings as described in the provided table.

    3. Choose Generate. A file named demo.zip is downloaded.

    Note
    If have encounter issues with the https://start.spring.io website, provide the file with the name: mta-intro-java-demo.zip[download]. Rename it to demo.zip and continue the exercise.
  5. In the Studio, in the mta-intro folder, upload the Java application provided in the demo.zip file. Rename the application project folder from demo to app2. Review, build and run the application.

    1. Drag the demo.zip file from its original folder (in Windows) and drop it on the mta-intro folder in the Studio.

    2. Choose TerminalNew Terminal

    3. In the terminal execute the following commands to unzip the archive:

      Code snippet
      unzip *.zip
      rm *.zip
      Copy code
    4. Rename the extracted demo folder to app2.

    5. In the terminal execute the following commands to build the application:

      Code snippet
      cd app2
      mvn clean install -U
      Copy code
    6. Navigate to app2/src/main/java/com/example/demo/DemoApplication.java.

    7. Wait a few seconds till the file is analyzed, then choose the Debug control that appears before the main method.

    8. Once the application has started, a pop up window appears stating: A service is listening to port 8080. Choose Open in New Tab. A new tab is opened showing the Whitelabel Error Page. This is an expected Spring Boot error, since the application has no controller method for the / path.

    9. Return to the Studio. Choose Stop and the debugger stops.

  6. In the Java application, create a rest controller class named DemoController, returning Hello Java! when opening the application with the Web browser.

    1. Create a new file app2/src/main/java/com/example/demo/DemoController.java containing the following code:

      Code snippet
      package com.example.demo;
      
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class DemoController {
      
          @GetMapping("/")
          public String hello() {
              
              String page = "<!DOCTYPE html><html><body>"
              + "<h1>Hello Java!</h1>"
              + "</body></html>";
          
              return String.format(page);
          }
      }
      Copy code
      You can copy the previous code from the mta-intro-01-democontroller-java.txt file [download].

    2. Re-build the application, then re-run the main method of the application. This time Hello Java! appears.

    3. Return to the Studio. Choose Stop and the debugger stops.

  7. Create two run configurations for the two module applications, called Launch Application 1 and Launch Application 2

    1. Choose RunOpen ConfigurationsJava. The mta-intro/.vscode/launch.json file is opened.

    2. Replace the full content of the file with the following content:

      Code snippet
      {
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "Launch Application 1",
                  "type": "pwa-node",
                  "program": "${workspaceFolder}/app1/main.js",
                  "request": "launch",
                  "skipFiles": [
                      "<node_internals>/**"
                  ]
              },
              {
                  "name": "Launch Application 2",
                  "type": "java",
                  "request": "launch",
                  "mainClass": "com.example.demo.DemoApplication",
                  "projectName": "demo"
              }
          ]
      }
      Copy code
      You can copy the previous code from the mta-intro-02-launch-json.txt file [download] .

  8. Create a MTA, including the two previous application projects. Use the following application names:

    • Name of the overall MTA: mta-intro
    • Name of the Node.js module: mta-intro-app1
    • Name of the Java module: mta-intro-app2
    1. In the mta-intro folder, create a file with name mta.yaml containing the following code:

      Code snippet
      ID: mta-intro
      _schema-version: '3.1'
      version: 0.0.1
      
      modules:
      
       - name: mta-intro-app1
         type: nodejs
         path: app1
      
       - name: mta-intro-app2
         type: java
         path: app2
      Copy code
      You can copy the previous code from the mta-intro-03-mta-yaml.txt file [download].

  9. Build the MTA in a .mtar archive.

    1. In the Studio, choose TerminalNew Terminal

    2. In the terminal, execute the following commands:

      Code snippet
      mbt build
      Copy code
      The two module projects are built and stored in a unique file named: mta_archives/mta-intro_0.0.1.mtar

  10. Deploy the .mtar archive to Cloud Foundry.

    1. In the terminal, execute the following commands:

      Code snippet
      cf login
      cf deploy mta_archives/mta-intro_0.0.1.mtar
      Copy code

      On login, you may be requested to enter your Cloud Foundry API Endpoint, email, and password.

      The archive is then deployed. The two module applications are created in Cloud Foundry.

  11. Look for the running applications in the SAP BTP Cockpit and open them.

    1. In a web browser, open your SAP BTP Cockpit based on the url you received at subscription time (for example: https://cockpit.eu20.hana.ondemand.com. If required, enter your e-mail and password.

    2. In the SAP BTP Cockpit, navigate to the training Subaccount. Navigate to the dev space.

    3. In Google Chrome, open the URL . If required, enter your e-mail and password.

    4. Choose the mta-intro-app1 application name.

    5. Choose the Application Route. The application shows Hello Node!.

    6. Go back and choose the mta-intro-app2 application name.

    7. Choose the Application Route. The application shows Hello Java!.

Task 2: Define Environment Variables as MTA Properties

Steps

  1. In both the module applications, enhance the program so that it reads the Hello! sentence from the environment variable TITLE. Enhance the lounch.json file including the variable for both modules. Check that the applications run successfully. Note the application runtime URLs for subsequent use.

    1. In the app1 folder, in the main.js file, replace the assignment of the page variable with the following code:

      Code snippet
      var title = process.env.TITLE;
      
          var page = "<!DOCTYPE html><html><body>"
              + "<h1>" + title + "</h/p>"
              + "</body></html>";
      Copy code
      You can replace the whole main.js content with the code in the mta-intro-04-main-js.txt file [download] .

    2. In the app2/src/main/java/com/example/demo/DemoController.java file, replace the assignment of the page variable with the following code:

      Code snippet
      String title = System.getenv("TITLE");
          String page = "<!DOCTYPE html><html><body>"
              + "<h1>" + title + "</h1p>"
              + "</body></html>";
      Copy code
      You can replace the entire DemoController.java content with the code in the mta-intro-05-democontroller-java.txt file [download] .

    3. In the .vscode/launch.json file, include the definition of the TITLE variable in both configurations, as shown in the following code:

      Code snippet
      "env": {
              "TITLE": "Hello Node!"
            }
      Copy code
      You can replace the entire launch.json content with the code in the mta-intro-06-launch-json.txt file [download].

    4. In the Studio, in the Debug window, run the two applications using the corresponding run configurations (they can run in parallel). Verify that the titles appear correctly at run time. Note the browser URL of both applications. Stop the execution.

      Note
      Sometimes we experienced be issues when the node.js application is started due to the port 3002 being busy after the previous run. In this case, consider closing and restarting the Studio development space.
      Note
      Recently we experienced an issue the java application not being automatically re-built before execution. To manually re-build the Java application, right click on the app2 folder, choose Open in Terminal. In the terminal run the following command:
      Code snippet
      mvn clean install -U
      Copy code
  2. In the mta.yaml file, define the TITLE variable as a property of the two modules. Build and deploy the application.

    1. In the mta.yaml file, include the definition of the TITLE variable in both module definitions, as shown in the following code:

      Code snippet
      properties:
           TITLE: "Hello Node!"
      Copy code
      You can replace the whole mta.yaml content with the code in the mta-intro-07-mta-yaml.txt file [download] .

    2. Build and deploy the application using the following commands:

      Code snippet
      mbt build
      cf deploy mta_archives/mta-intro_0.0.1.mtar
      Copy code
      If there are any issues, login to Cloud Foundry again.

  3. Look for the running applications in the SAP BTP Cockpit and open them. Verify that the TITLE variable appears in the User-Provided Variables for both apps.

    1. In the SAP BTP Cockpit, navigate to the dev space.

    2. Choose the mta-intro-app1 application name.

    3. Choose User-Provided Variables and verify that the TITLE variable is created.

    4. Choose Overview, choose the Application Route. The application displays: Hello Node!.

    5. Repeat the same steps for the mta-intro-app2 application.

Task 3: Define Module Dependencies and Exchange Variables

Steps

  1. In both the module applications, enhance the program so that a hyperlink appears under the title, referencing to the other application. As this link is determined at deploy time, you need to store it in an environment variable so that you can populate it during deployment. Enhance the lounch.json file including variables for both modules (use names A1URL and A2URL). Check that the applications run successfully.

    1. In the app1 folder, in the main.js file, replace the assignment of the page variable with the following code:

      Code snippet
      var title = process.env.TITLE;
          var a2url = process.env.A2URL;
      
          var page = "<!DOCTYPE html><html><body>"
              + "<h1>" + title + "</h1>"
              + "<p>Navigate to <a href=\"" + a2url + "\">Application 2</a></p>"
              + "</body></html>";
      Copy code
      You can replace the entire main.js content with the code in the mta-intro-08-main-js.txt file [download] .

    2. In the app2/src/main/java/com/example/demo/DemoController.java file, replace the assignment of the page variable with the following code:

      Code snippet
      String title = System.getenv("TITLE");
              String a1url = System.getenv("A1URL");
              String page = "<!DOCTYPE html><html><body>" 
              + "<h1>" + title + "</h1>" 
              + "<p>Navigate to <a href=\"" + a1url + "\">Application 1</a></p>" 
              + "</body></html>";
      Copy code
      You can replace the entire DemoController.java content with the code in the mta-intro-09-democontroller-java.txt file [download] .

    3. In the .vscode/launch.json file, include the definition of the A1URL and A2URL variable in the proper configurations. Enter the values you noted previously. See an example below of how it will display (your actual URLs will be different):

      Code snippet
      {
        "version": "0.2.0",
        "configurations": [
          {
            "name": "Launch Application 1",
            "type": "pwa-node",
            "program": "${workspaceFolder}/app1/main.js",
            "request": "launch",
            "skipFiles": [
              "<node_internals>/**"
            ],
            "env": {
              "TITLE": "Hello Node!",
              "A2URL": "https://9c235a74trial-workspaces-ws-ld7zh-app3.eu10.trial.applicationstudio.cloud.sap/"
            }
          },
          {
            "name": "Launch Application 2",
            "type": "java",
            "request": "launch",
            "mainClass": "com.example.demo.DemoApplication",
            "projectName": "demo",
            "env": {
              "TITLE": "Hello Java!",
              "A1URL": "https://9c235a74trial-workspaces-ws-ld7zh-app2.eu10.trial.applicationstudio.cloud.sap/"
            }
          }
        ]
      }
      Copy code
      You can replace the entire launch.json content with the code in the mta-intro-10-launch-json.txt file [download] (replace the URLs with your actual values).

    4. In the Studio, in the Debug window, run the applications in parallel using the corresponding run configurations. Verify that the hyperlinks appear correctly at run time. Stop the execution.

      Note
      Recently we experienced an issue the java application not being automatically re-built before execution. To manually re-build the Java application, right click on the app2 folder, choose Open in Terminal. In the terminal run the following command:
      Code snippet
      mvn clean install -U
      Copy code
  2. In the mta.yaml file, define the A1URL and A2URL variables as properties. Populate them with deploy time URL values provided by the relative module. Build and deploy the application.

    1. In the mta.yaml file, include the definition of the A1URL and A2URL variables, as shown in the following code:

      Code snippet
      ID: mta-intro
      _schema-version: '3.1'
      version: 0.0.1
      
      modules:
      
       - name: mta-intro-app1
         type: nodejs
         path: app1
         requires:
          - name: app2-provided
         provides:
          - name: app1-provided
            properties: 
              url: ${default-url}
         properties:
           TITLE: "Hello Node!"
           A2URL: ~{app2-provided/url}
      
       - name: mta-intro-app2
         type: java
         path: app2 
         requires:
          - name: app1-provided
         provides:
          - name: app2-provided
            properties: 
              url: ${default-url}
         properties:
           TITLE: "Hello Java!"
           A1URL: ~{app1-provided/url}
      Copy code
      You can replace the entire mta.yaml content with the code in the mta-intro-11-mta-yaml.txt file [download].

    2. Build and deploy the application using the following commands:

      Code snippet
      mbt build
      cf deploy mta_archives/mta-intro_0.0.1.mtar
      Copy code
      In case anything goes wrong, login to Cloud Foundry again.

  3. Look for the running applications in the SAP BTP Cockpit and open them. Verify that the A1URL and A2URL variables appear in the User-Provided Variables with proper values.

    1. In the SAP BTP Cockpit, navigate to the dev space.

    2. Choose the mta-intro-app1 application name.

    3. Choose User-Provided Variables and verify that the A2URL variable is created.

    4. Choose OverviewApplication Route. The application shows Hello Node!. Then it shows a link Navigate to Application 2. If you click on the link, the Hello Java! application displays.

    5. Repeat the same steps for the mta-intro-app2 application.

Save progress to your learning plan by logging in or creating an account