Introduction

This book contains a set of tutorials showcasing several use cases where Kuwaiba can be applied effectively, as well as platform operation and development tips.

Modeling

DWDM Ring

This example takes three sites with DWDM multiplexers created from scratch and from a template, and connect them in a ring topology using the Object View and the Outside Plant Manager module.

VAS Platforms

This example show a way to model a set of mobile VAS platforms. It is a basic example for someone starting their journey with Kuwaiba and who is wondering how to model applications and services.

Platform Operation

Bulk Upload

This tutorial describes how to run one of the data on-boarding examples available in the code repository, and sketches the basics of data ingesting in Kuwaiba.

Development

Creating a New Module

This example demonstrates how to extend Kuwaiba by creating a module using the Integration API, and manage inventory objects using BusinessEntityManager.

DWDM Ring

Configuring the Templates

Templates are predefined, reusable containment structures. They can be created for any kind of element in the inventory, even physical connections, logical structures or services (as in Customer or Resource Facing Services). The Template Manager is available in the Administration menu. In this example, we are going to create a basic template for this multiplexer, which happens to have 15 slots in its biggest flavor.

First, open the Template Manager and search for the class you are going to create a template for, in this example, DWDMMux.

Creating a template for a DWDM multiplexer

Set the default attribute values in the property sheet on the right. For this example, we had previously created a Huawei OSN1800 V entry in the EquipmentModel list type. To create the slots, use the "+" button next to your new template. Choose single or multiple according to your needs. If you chose multiple, use a pattern as instructed in the user manual. The inner elements are created from the "..." menu next to the parent object. In this example, we will create a control board in the first slot, and communications boards with single ports in the next 2.

A template for a DWDM multiplexer

If you require SFPs, create them as Transceiver instances under the boards, and create a regular port under them. Change the containment configuration if required.

Transceiver containment configuration

Creating the Devices

Now that we have a template, we are going to create three multiplexers in three different buildings. Note that we will just create one of them using a template, the other buildings will be copied and renamed from the original. The figure below shows a building with a room and a rack.

A building with a room and a rack

Now, from the rack we can launch the Create from Template action from the Basic Actions section, or the ... button next to the rack, and actually create the multiplexer. In the same rack we will place an ODF, also created from a template.

A building with a room and a rack

ODFs (and D/MDF for that matter) deserve a special mention. In Kuwaiba, distribution frames are modeled as elements with the same number of input and output ports, this emulates the tray that it's inside the ODF that serves as splicing point between the inbound fiber strands and the pigtails connected to the ports in the front of the panel. By default, input and output ports are disconnected, you have to connect them using what we call a mirror (see more details in the Physical Connections chapter of the User's Manual). This mirror, back-to-back connection between ports is useful to model several scenarios, but for now, we will use them only to represent a splicing function. Mirrors can be created in the template, but this feature is disabled in this version of Kuwaiba (it might be back later, but for now it's only available in the development version 2.5), so we'll have to create the mirrors once the ODF is created. Naming the ODF ports FRONT-XX/BACK-XX is not mandatory, but will simplify things later, as we will see.

ODF template

Now that the template is ready, we can create the ODF as a sibling of the multiplexer inside the rack.

ODF in the rack

After the ODF has been created, we can mirror the ports by launching the Manage Port Mirroring action from the Advanced Actions menu. Click the Automatic Mirror Matching button and confirm the operation. This step is not precisely intuitive, but we'll re-evaluate UI in coming versions. This will leave the ODF ready to be connected.

Connecting the Devices

There are two types of connections in Kuwaiba: Containers and Links. The latter are anything that can connect two ports (fibers, coaxial/ethernet cables, telephonic pairs, power cables, etc). The former, as its name indicates, can contain other containers and links. To put it graphically, these are containers and these are links. You can find more information about both in the User's Manual. You can create your own types of both, but we won't get into that today. Suffice to say, that we will use containers (with fibers -OpticalLinks- inside) to connect buildings, and simple links (fibers) to connect devices in the same rack.

Let's start with the inside plant. There are several ways to create connections in Kuwaiba, but we are going to use the simplest method: The Object View. Select the rack and open the Views section, and click on Object View

Rack's Object View

Views are graphical representations of selected objects (Other views are discussed in the User's Manual). The Object View is the simplest of these views, and shows the direct children of a given object, as well as their connections. You can add background images (for example floor plans in inside plant scenarios), connect elements and export the view, among other things. To connect the ODF and the multiplexer, click on the plug icon of any of the end points, and drag it to the target.

Connection in an Object View

That will launch a quick wizard where you can name the connection, select its type, and optionally, choose a template as shown in the picture below.

Connection in an Object View

Note: The screenshot says Fiber, but that was just the display name of OpticalLink in the database used for these examples.

In the final steps, choose the ports

Choosing the endpoints of the connection

That's it. If you see a yellow line between the ODF and the multiplexer, you did it correctly (the connection color is customizable. It's the color assigned to the class OpticalLink in the Data Model Manager). Now we can launch a Physical Path, which is a view that shows the physical continuity from a given port. Select the port in the multiplexer you chose to connect and click on Physical Path in the Views section.

Physical path

Note: The port appears blue, with a [+] in its name. That can be done with Validators. Validators are customizable pieces of logic that check for a condition you code, and can influence the way inventory objects are displayed in the GUI. You can do some pretty neat things with them, but that will be discussed in another tutorial. The sample database has a few validators in it. The empty database has none.

Summary

So far, we have created a single site with a DWDM multiplexer and an ODF, and connected them using an OpticalLink (fiber) by opening the parent rack's Object View and using the physical connection tool. We also learned to create Templates, and the concept of mirror as a way to bridge two ports back-to-back to provide continuity to a connection. In the next section, we will clone this site two more times, rename the relevant objects, and connect all the sites using containers in order to form a ring.

Cloning the Original Site

We will use the Copy to... operation available in the Basic Actions section or the ... button next to the object we want to copy. This will open a so-called Simple Object Selector.

Copy to... action

This Simple Object Selector is used in several contexts. Just type the first letters of the name of the target object or its class and pick it from the drop-down menu. In this case, we want to copy the original building inside its parent object (the city). Note that although you can pick any object in the selector, only objects allowed by the containment configuration will result in a successful copy (i.e. if you try to copy the Building to, say, a Router, an error message will be displayed). After renaming the relevant objects (building, rack, mux and ODF at least), you should end up with three sites as depicted in the picture below.

All nodes cloned

Tip: You can rename an object using the property sheet by double clicking the field name or pressing F2.

Connecting the Sites

Using the Object View

Once the nodes have been copied, we are going to connect them. Open the Object View as instructed in picture above. We will now connect building SFA-BUI-01 to SFA-BUI-02 like we did in the past section, but in this case, we are going to use a Container (that is, a conduit) instead of a Link. We will use a WireContainer (WireContainers are used to contain copper-based and optical connections, whereas WirelessLinks are used to contain wireless links (technically known as RadioLinks). You can create your own types of containers -though in most occasions this is not necessary- by subclassing GenericPhysicalContainer in the Data Model Manager). Containers and Links, like any other class in Kuwaiba, can have templates. In the sample database you will find two templates for WireContainer: One is a conduit that has 4 other smaller conduits inside, each of them with 4 fibers. The other is a cable with a single strand (might be a drop cable). You can create your own templates with real-life conduits (for example with 96+ fibers inside), just take into account that the physical connections model requires that everything inside a container is a so-called special child. We won't go into details here because this is a separate topic, just make sure you use the options indicated in the picture below.

Creating a container template

Connecting two buildings will bring up a familiar wizard, but this time, we'll be using a WireContainer and the template with sub-containers.

Connecting sites, step one

In the next step we select the two buildings

Connecting sites, step two

Repeat the procedure between SFA-BUI-01 and SFA-BUI-03, but NOT between SFA-BUI-02 and SFA-BUI-03. For these we'll use another way. If we followed the steps, the city's Object View should look like in the picture below. In case you are wondering, we will connect the fibers last.

Sites connected using the Object View

Note: This time the connections are purple, not yellow. Again, this color correspond to the color of the class (WireContainer or OpticalLink).

Using the OSP Module

For the third arm we could do it the same way, but instead of that, we are going to use the Outside Plant Manager. This module adds a spatial dimension to the inventory. First, we are going to create a new OSP View, and name it and center the map in San Francisco.

New OSP View

The default map provider is OpenStreeMap, but we'll be using Google Maps in the following screenshots. The behavior is the same for the sake of this example. Click the Add Node button, and in the filter text field, type SFA-BUI and hit Enter. If you followed the naming conventions, you should see the three buildings we created previously.

Adding nodes to the OSP View

After selecting the nodes to be added, you will notice that the mouse pointer becomes a crosshair. If the building had geo-coordinates set previously, the system will ask you if you wish to override them or use them. Since we haven't set them yet, the nodes will be placed one after the other in the position you indicate.

Nodes added to the OSP View

Now let's import the existing connections, and for this, use the button to the right of Add Nodes. In the form, select the endpoints of the connections you want to import. The system will detect the existing containers between the nodes.

Adding connections to the OSP View

Important

An OSP view can only contain nodes that are objects of subclasses of GenericLocation, such as Buildings, Manholes, Poles, Houses and connections that are subclasses of GenericPhysicalContainer, such as WireContainer or WirelessContainer.

If you click the container, it will be added automatically, and you will be asked if you want to connect the fibers inside (Edit Connections, in fact) as can be seen in the picture below.

Connections added to the OSP View

We want to connect the back ports of the ODFs on each side using the first fiber of the first subconduit. On the SFA-BUI-01 side, you will notice that the front port is already connected, since we connected the devices to the corresponding front ports. You don't have to connect both sides, but we'll do it in this example

Connecting the links in an imported container

Note

If it's relevant for your application, you can also create the lambdas under the OpticalLinks (as Special Children) and later relate them to services or logical resources like virtual circuits. They are not to be connected, as they are not either Links or Containers, they act like channels that use the physical medium. Using lambdas

With the Selection Tool (the button with the hand icon), you can select the container and change its route. Do the same with the container connecting SFA-BUI-03.

Changing the route of a container

There are several Configuration Variables that govern label colors and zoom levels at which labels are visible. Finally, we are going to create the final arm of the ring between SFA-BUI-02 and SFA-BUI-03. To do this, we will select the Connection Tool, then select the source building and trace the route in the map until we reach the target node.

Creating a container in the OSP module

Clicking the target node will launch a similar wizard to the one we saw before, and by the end you will be offered to connect the fiber inside.

Creating a container in the OSP module

You can edit the connections of a given container at any moment by right-clicking it and selecting the option in the context menu. You can also launch the wizard from the Advanced Actions menu in the Navigation module, using the Edit Connections action.

Launching Edit Connections from the Navigation module

In the end, the ring should look like this:

Full ring

Finally, if you launch a Physical Path from the port of the first communication board of any multiplexer, you should be able to see how it reaches the next multiplexer through the ODFs on both sites and the fiber you selected in the Edit Connections action.

Full Physical Path

Getting Started with Kuwaiba

This is a very basic tutorial. When you are faced with a new tool, perhaps the most direct way to understand how it works is by getting hands-on and creating something. This tutorial will help you model a basic short messaging system using Kuwaiba.

However, I recommend doing some preliminary work to ensure that your idea is effectively translated into the tool. The first thing we will do is list the key elements of your model. In my case, I will work on a classic VAS (Value-Added Service) system: a short messaging system connected to the core network via SIGTRAN and to the BSS (Business Support Systems) via APIs. I have chosen this system because it represents the basic functionality of many value-added services and other telematics-oriented services.

Components

Servers

Physical Equipment: These will host the services.

Services

We will create four services:

  1. Short Message Center (SMC): Responsible for receiving, processing, routing, and storing text messages in memory for the cellular network (SMS messages of 160 characters as per the SMPP 3.4 protocol).
  2. Billing Server: Responsible for generating Call Detail Records (CDRs).
  3. Reporting Server: Handles the creation of various reports.
  4. Core Network Communication Server: This service manages the relationship with a Signaling Transfer Point (STP) in the core network using the SIGTRAN protocol to handle communication within a 3G/4G/5G network.

Additional Equipment

To make this work, we will need other equipment such as databases, networking gear, fiber optics, and UTP cables.

Now, let's create a diagram that relates these elements. This will help us improve our model and possibly include elements that were not initially present but are necessary (such as a rack, a datacenter, or perhaps electrical equipment). This can take you to the level of detail you want, but for now, it will be something basic.

Diagrama primario
Figure 1: Basic Diagram of Components

Now we are going to start transferring this graphical model to Kuwaiba. As a first step, we will locate our racks (A-B) inside a room located in a building (Datacenter A) in an imaginary city called Fruncia.

To do this, we will use the "navigation" module:

navigation module
Figure 2: Navigation Module

Let’s start from the root by clicking on "Go to root", which will display some "countries" or "continents" that were created earlier. At this point, we could create an imaginary continent or include Europe or any starting point by clicking on "root actions/new Object".

In our case, we will create Fruncia within America. So, we will click on America:

navigation from root
Figure 3: Navigation from Root to America

Then, we will click on the three dots in front of America and create a new object called Fruncia.

Next, we will look for the three dots for the Fruncia object. A dialog will appear asking what kind of class we will create. We will choose the appropriate type for each case, such as a country. We will do the same by creating a building and then a datacenter:

creating objects of class
Figure 4: Creating Objects of Class

This means we are creating a structure where a continent contains a country, that country contains cities and buildings, and those buildings contain datacenters.

Of course, I skipped many details (remember that this is a basic tutorial), but we could have a very detailed structure, with all kinds of details... region, district, neighborhood, floor, etc.

navigation while creating objects
Figure 5: Navigation While Creating Objects
more objects
Figure 6: Creating More Objects
more objects
Figure 7: More Objects Created
more objects
Figure 8: Continuing to Create Objects
more objects
Figure 9: Additional Object Creation

I created several racks, thinking of a real example of a similar distribution, where in a single datacenter there were core equipment, networking equipment, VAS equipment, and OSS/BSS, all on different rows of racks, connected by 24-port L2 switches. In this case, we will have one rack with three servers connected to a switch, which is then connected to another switch in a different rack where the BSS and Core racks are located.

Racks
Figure 10: Racks in Datacenter01

Now, what we are going to do is place the servers in each of the racks. However, we need to take a preliminary step because the servers in the tool, by default, may contain optical ports, and I require that my design includes electrical ports. Therefore, I need to use the Containment Manager to modify the containment hierarchy of the servers.

Containment Manager
Figure 11: Containment Manager Interface

To do this, I will search for the Server class and, using the search function, I will add electrical ports as children, as shown in the following image:

Add Electrical Ports to Server Class
Figure 12: Adding Electrical Ports to Server Class

Bulk Upload in Kuwaiba

Introduction

There are several scenarios when you need to automated the creation of many objects from one or multiple sources. While Neotropic SAS has a proven Migration Framework to deal with ETL requirements in big network inventory projects, here you will learn how to create simple tasks for you day-to-day data ingestion needs in Kuwaiba.

In early versions of Kuwaiba, there used to be a Bulk Upload functionality. It defined a simple format of plain text file, and each line had a syntax that told the ingestion algorithm how to process it. It was useful, but pretty limited when more complex business rules were involved, and the processing of each line was stateless, limiting its performance when some lines used information from previous ones. Other optimizations were not possible, and direct access to the database was not allowed. This feature was dropped in version 2.0.x in favor of Task Manager scripts. The main objective of the Task Manager is to provide a way to automate tasks in Kuwaiba. Tasks are Groovy/Java scripts that leverage the different integration APIs in Kuwaiba (such as the Persistence API, that abstracts the access to the database and exposes methods to manipulate the inventory objects regardless their nature) in order to perform simple or complex actions. Having the possibility to use the full power of a programming language and direct access to the database, a system administrator can create, among other things, powerful and performant routines to process and ingest data. How to code scripts and use the available APIs is outside the scope of this document, but you can find a plethora of examples in the official code repository not only of tasks, but also validators, reports and filters. The following steps will guide you through the process to use an on-boarding script to import a basic containment structure.

On-boarding Process

  1. Download the sample script from the repository
  2. Go to the Task Manager module and click on New, and paste the contents of the script in the editor. make sure you read carefully the header with additional instructions and tips.

New task

  1. Download the sample import file from the repository. This file contains a few lines representing Rooms inside Central Offices, inside Cities.
  2. Place the sample file in a location readable by the server. If you are using Docker, inside the container filesystem (volatile), or on an external mounted volume (persistent).
  3. Make sure the Commit on Execute option is unchecked. This will help you test the results before actually modifying the database. No changes will be committed until you set this option to true.

Commit on Execute

  1. Set the fileName task parameter to your import file location.

Setting the file location

  1. Run the task. Running the task will save the script automatically. Once you see all messages in green, check the "Commit on Execute" and run the task again.

Running the Task

Further Steps

  • Most import scripts look like that, plus optimization routines (caching strategies, direct access to the database, etc). Make sure you take a good look at the methods of the BusinessEntityManager, which is part of the Persistence API, and handles most of the basic inventory object manipulation logic. His siblings MetadataEntitymanager and ApplicationEntityManager perform equally important tasks.
  • The repository has another example closer to a real-world scenario. This script processes the hardware export file of Huawei's U2000 DWDM NMS. Check it out, you will learn a couple of tricks from it.
  • Kuwaiba 2.5's Task Manager brings important improvements in terms of API scope/structure and code management facilities. Stay tuned for further developments.

Creating a New Module

Modules in Kuwaiba help structure and organize various aspects of the system, facilitating the management of a wide range of resources and functionalities. They adapt to the changing requirements of the business and technological environment. Additionally, you can model any aspect relevant to everyday life.

Create a Module

Kuwaiba Modules

Application modules are located in the Modules folder of the main application.

Kuwaiba handles 3 types of modules:

  • Core Modules: Main modules of the application.
  • Optional Modules: These are additional modules specific for telecommunications management that are not essential for the basic operation of Kuwaiba. Although Kuwaiba can operate without these modules, they can be useful for users who need telecommunication-related functionalities.
  • Commercial Modules: Modules designed to be licensed commercially and that will not be open source, providing functions for more specific telecommunications technologies.

In the Modules folder you can create your own module:

Kuwaiba Root
Figure 1: Kuwaiba Modules

Create a Java application with Maven and name it as you prefer (In this example, it was named RentHouse):

Create new Project
Figure 2: Creating a New Project

Your Project:

Core Modules Root
Figure 3: Module Created

Web Client

In the main Kuwaiba application, we also have the Web Client, which serves as the entry point for the entire project.

Open the Web Client Application in the Main Kuwaiba Application:

Web Client
Figure 4: Web Client

Right-click on Dependencies and then click on Add Dependency:

Web Client Dependencies folder
Figure 5: Web Client Dependencies folder

Select your project and add it to dependencies:

Web Client Dependency Added
Figure 6: Web Client Dependency Added

Note

You can also add the dependency directly by editing the pom.xml file.

Module Structure:

Create the following Packages within the Source Packages of your Module:

  • persistence.
  • (Your module name), for this example renthouse.

Note

Verify that your Packages follow this structure:

org.neotropic.kuwaiba.modules.YOUR_PACKAGE

Rent House Structure
Figure 7: Rent House Packages Structure

Create the following Classes within the previously created Packages:

Classes of each Package
Figure 8: Classes of each Package
  • persistence
    • RentHouseService: The RentHouseService class is a Spring service component to facilitate interaction with inventory objects.
  • renthouse
    • RentHouse: The RentHouse class is a Spring component to define a specific module within the Kuwaiba application.
    • RentHouseLayout: This class is designed to define the layout structure for the Rent House module.
    • RentHouseUI: The RentHouseUI class is a Vaadin UI component designed to provide the user interface for the Rent House module.

Later, we will write the code that should go into each class.

Persistence API

Contains the definition of the classes and interfaces necessary for communication with the database. For this purpose, Kuwaiba uses the Persistence API, which allows you to manage data in the database.

Open the Persistence API Application in the Core Modules of the Main Kuwaiba Application:

Persistent API
Figure 9: Persistence API

Add Persistence API to your module dependencies, right-click on Dependencies and then click on Add Dependency:

Rent House Dependency
Figure 10: RentHouse Dependencies folder

Select Persistence API and add it to dependencies of your Module:

Persistence API Dependency Added
Figure 11: Persistence API Dependency Added

Note

You can also add the dependency directly by editing the pom.xml file.

Consume the Kuwaiba service:

BusinessObject and BusinessObjectLight

Since Kuwaiba's data model is dynamic, the system allows you to create any object you need to manage your inventory, providing high flexibility and customization in its administration.

In Kuwaiba there are two types of Classes to create inventory objects:

  • BusinessObject: It's a class that is used to map the inventory objects.
  • BusinessObjectLight: It's the super class of Business Object.

BusinessObjectLight allows you to manage objects with the essential attributes of an entity in the database, such as id, name, and className. On the other hand, BusinessObject also includes these basic attributes and allows you to create objects with additional attributes, such as the creation date.

For the implementation of the example, we will use BusinessObjectLight to display the houses registered in the inventory, along with their basic attributes: id, name, and className. But first, we must understand some other concepts, which will be explained later.

Entity Manager Interfaces

They are interfaces that define fundamental operations and interactions with different aspects of the system. In Kuwaiba, there are three types of Entity Managers, each serving a distinct purpose:

  • MetadataEntityManager:Responsible for data model manipulation.
  • BusinessEntityManager: Used to manipulate inventory objects, including adding, removing, updating, and retrieving items from the inventory.
  • ApplicationEntityManager:Responsible for everything related to the application, such as user management and session handling.

Internationalization and Localization Module

It's used to manage and adapt the content of Kuwaiba to different languages and regions.

Internationalization and Localization Module
Figure 12: Internationalization and Localization Module

Modify messages_en_US.properties and messages_es_CO.properties files:

Internationalization and Localization Module Structure
Figure 13: Internationalization and Localization Module Structure

Add the following content in the messages_en_US.properties file:

    module.rent.house.name=Rent House Module
    module.rent.house.description=Rent House Module description...
    module.rent.house.title=Rent House :: Kuwaiba Open Network Inventory

Add the following content in the messages_es_CO.properties file:

    module.rent.house.name=Renta de casas
    module.rent.house.description=Renta de casas descripcion...
    module.rent.house.title=Renta de casas :: Kuwaiba Open Network Inventory

Translation Service

This interface provides translation services.

    @Autowired
    private TranslationService ts;

Use the Translation Service:

    public String getTranslation() {
        //Use the key from the internationalization file that you added
        return ts.getTranslatedString("module.rent.house.name");
    }

We will need the steps used in Internationalization and Localization Module and Translation Service later.

Using Business Entity Manager

Now that we have covered the previous concepts, let's begin writing the code for each class.

Consume the service through BusinessEntityManager interface. Insert the following code into your service Class:

    @Service
    public class RentHouseService {
        
        @Autowired
        private BusinessEntityManager bem; 
        
        public RentHouseService(){
            
        }
        
        public List<BusinessObjectLight> findAllBusinessObjectLight(String className,long page,int maxLimit ) 
                throws MetadataObjectNotFoundException, InvalidArgumentException{
            List<BusinessObjectLight> listObject = new ArrayList();
            listObject = this.bem.getObjectsOfClassLight(className, page, maxLimit);
            return listObject;
        }
    }

You can access the BusinessEntityManager interface to explore other services that Kuwaiba provides for managing inventory objects.

Insert the following code into your Module Class:

    @Component 
    public class RentHouse extends AbstractModule{

        public static final String MODULE_ID = "renthouse";
    
        @Autowired
        private ModuleRegistry moduleRegistry;
        
        @Autowired
        private TranslationService ts;
        
        @PostConstruct
        public void init() {
            // Register the module itself
            this.moduleRegistry.registerModule(this);
        }

        @Override
        public String getName() {
            return this.ts.getTranslatedString("module.rent.house.name");
        }

        @Override
        public String getDescription() {
            return this.ts.getTranslatedString("module.rent.house.description");
        }

        @Override
        public String getVersion() {
            return "2.1.1";
        }

        @Override
        public String getVendor() {
            return "Neotropic SAS <contact@neotropic.co>";
        }
        
        @Override
        public String getId() {
            return MODULE_ID;
        }

        @Override
        public AbstractModule.ModuleType getModuleType() {
            return AbstractModule.ModuleType.TYPE_OPEN_SOURCE;        
        }

        @Override
        public int getCategory() {
            return CATEGORY_ADMINISTRATION;
        }
    }

Insert the following code into your Layout Class:

    // Use the basic Kuwaiba layout
    public class RentHouseLayout extends ModuleLayout{ }

Create your view inside your UI Class:

    // renthouse is the route of your view
    @Route(value = "renthouse", layout = RentHouseLayout.class)
    public class RentHouseUI extends VerticalLayout implements HasDynamicTitle,AbstractUI{
        
        private final String MODULE_NAME = "RENT HOUSE BY: Neotropic SAS";
        
        @Autowired
        private RentHouseService rhs;
        
        @Autowired
        private TranslationService ts;
        
        private H3 title;
        
        private Grid<BusinessObjectLight> gridObjects;
        
        public RentHouseUI(){
            super();
            setSizeFull();
        }
        
        @Override
        public void initContent() {
        createTitle();
        createGridObjects();
        }
        
        private void createTitle(){
            this.title = new H3(MODULE_NAME);
            add(this.title);
        }
        
        private void createGridObjects(){
            try{
                List<BusinessObjectLight> objects = new ArrayList();
                
                objects = this.rhs.findAllBusinessObjectLight("House", 1, 10);
                
                this.gridObjects = new Grid<>(BusinessObjectLight.class, false);
                
                this.gridObjects.addColumn(BusinessObjectLight::getId).setHeader("ID");
                this.gridObjects.addColumn(BusinessObjectLight::getClassName).setHeader("Class Name");
                this.gridObjects.addColumn(BusinessObjectLight::getName).setHeader("Name");
                
                this.gridObjects.setItems(objects);
                
                add(this.gridObjects);
                
            }catch(InvalidArgumentException | MetadataObjectNotFoundException ex){
                new SimpleNotification(ts.getTranslatedString("module.general.messages.error"), ex.getLocalizedMessage(),
                        AbstractNotification.NotificationType.ERROR, ts).open();
            }
        }

        @Override
        public String getPageTitle() {
            return this.ts.getTranslatedString("module.rent.house.title");
        }
    }

Enable your Module

Go to User Manager:

User Manager
Figure 14: User Manager

In the Administrators section, look for and enable your module for the Neotropic Customer (admin):

Enable Module
Figure 15: Enable the Module

Navigate to your view:

Enable Module
Figure 16: Rent House View