Custom Stack - Facade
Overview
This section will guide you through the process of creation of Java Facade and TypeScript API for the Eclipse Dirigible Custom Stack.
Prerequisites
Steps
Create APIs Module
- Navigate to the root folder of the custom stack (e.g.
<my-custom-stack-path>/custom-stack). - Create
apisfolder and navigate to it. - Create
pom.xml,MyFacade.java,MyApi.ts,project.jsonandtsconfig.jsonfiles.
- Create new
apis/pom.xmlfile. - Paste the following content:
apis/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.dirigible.samples</groupId>
<artifactId>custom-stack-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>custom - stack - apis</name>
<artifactId>custom-stack-apis</artifactId>
<packaging>jar</packaging>
</project>
Note
The creation of a Java facade is optional, as the same logic can be wrapped/implemented in the TypeScript API only by using the Java.type() function.
- Create
src/main/java/io/dirigible/samples/folder stucture and navigate to it. - Create new
apis/src/main/java/io/dirigible/samples/MyFacade.javafile. - Paste the following content:
apis/src/main/java/io/dirigible/samples/MyFacade.java
package io.dirigible.samples;
public class MyFacade {
public static String greet() {
return "Hello, welcome to my custom Eclipse Dirigible stack!";
}
public int add(int a, int b) {
return a + b;
}
public int multiply(int a, int b) {
return a * b;
}
public String customMethod(String input) {
// Your custom logic here
return "Processed input: " + input;
}
}
- Create
src/main/resources/META-INF/dirigible/custom-api/folder stucture and navigate to it. - Create new
apis/src/main/resources/META-INF/dirigible/custom-api/MyApi.tsfile. - Paste the following content:
apis/src/main/resources/META-INF/dirigible/custom-api/MyApi.ts
const MyFacade = Java.type("io.dirigible.samples.MyFacade");
export class MyApi {
private facadeInstance = new MyFacade();
public static greet(): string {
return MyFacade.greet();
}
public add(a: number, b: number): number {
return this.facadeInstance.add(a, b);
}
public multiply(a: number, b: number): number {
return this.facadeInstance.multiply(a, b);
}
public customMethod(input: string): string {
return this.facadeInstance.customMethod(input);
}
}
Access to Java Classes
Java classes can be accessed through the Java.type() function by providing the Fully Qualified Name (FQN) (e.g. io.dirigible.samples.MyFacade):
const MyFacade = Java.type("io.dirigible.samples.MyFacade");
To invoke static method of the MyFacade class:
const MyFacade = Java.type("io.dirigible.samples.MyFacade");
MyFacade.greet();
To create class instance and call a method:
const MyFacade = Java.type("io.dirigible.samples.MyFacade");
const facadeInstance = new MyFacade();
facadeInstance.add(5, 3);
Add Module Dependency
- Navigate to the root folder of the project (e.g.
<my-custom-stack-path>/custom-stack). - Open the
pom.xmlfile. - Make the following changes:
- Navigate to the
<modules>section. -
Add the following module:
<modules> <module>apis</module> <module>application</module> <module>branding</module> </modules>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<name>custom - stack - parent</name>
<description>Custom Stack - Sample</description>
<groupId>io.dirigible.samples</groupId>
<artifactId>custom-stack-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<inceptionYear>2024</inceptionYear>
<url>https://www.dirigible.io</url>
<organization>
<name>Eclipse Foundation</name>
<url>https://www.eclipse.org</url>
</organization>
<scm>
<url>https://github.com/dirigiblelabs/tutorial-custom-stack</url>
</scm>
<modules>
<module>apis</module>
<module>application</module>
<module>branding</module>
</modules>
<dependencies>
<!-- Platform -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>compile</scope>
</dependency>
<!-- Commons -->
<dependency>
<groupId>org.eclipse.dirigible</groupId>
<artifactId>dirigible-commons-config</artifactId>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Date Type Utils -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${org.springdoc.openapi.ui.version}</version>
</dependency>
<!-- Data Access -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- WebJars -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>${webjars-locator}</version>
</dependency>
<!-- Olingo -->
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>olingo-odata2-lib</artifactId>
<version>${olingo.version}</version>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.dirigible</groupId>
<artifactId>dirigible-dependencies</artifactId>
<version>${dirigible.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<rule>
<element>SOURCEFILE</element>
<excludes>
<exclude>*src/test/*</exclude>
</excludes>
</rule>
</rules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<project.title>custom stack</project.title>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dirigible.version>10.2.7</dirigible.version>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.resource.plugin.version>3.3.0</maven.resource.plugin.version>
<maven.clean.plugin.version>3.2.0</maven.clean.plugin.version>
<maven.clean.plugin.directory>src/main/resources/META-INF/dirigible</maven.clean.plugin.directory>
<maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven.scm.plugin.version>1.13.0</maven.scm.plugin.version>
<scmVersionType>branch</scmVersionType>
<commons.io>2.11.0</commons.io>
<commons.codec>1.15</commons.codec>
<commons.lang3>3.12.0</commons.lang3>
<commons.exec>1.3</commons.exec>
<commons.text>1.10.0</commons.text>
<gson.version>2.10.1</gson.version>
<mockito.version>4.11.0</mockito.version>
<hamcrest.all.version>1.3</hamcrest.all.version>
<retrofit.version>1.8.0</retrofit.version>
<okhttp3.version>4.10.0</okhttp3.version>
<slf4j.version>1.7.36</slf4j.version>
<slf4j.simple.version>1.7.12</slf4j.simple.version>
<logback.version>1.4.5</logback.version>
<commons-dbcp2.version>2.9.0</commons-dbcp2.version>
<postgresql.version>42.7.0</postgresql.version>
<ngdbc.version>2.20.11</ngdbc.version>
<snowflake.version>3.15.0</snowflake.version>
<activemq.version>5.17.3</activemq.version>
<jsr250-api.version>1.0</jsr250-api.version>
<jetty.version>9.4.48.v20220622</jetty.version>
<lucene.version>9.4.2</lucene.version>
<chemistry.version>1.1.0</chemistry.version>
<flowable.version>6.8.0</flowable.version>
<jaxb.version>2.3.0</jaxb.version>
<jaxws.version>2.3.3</jaxws.version>
<jakarta.ws.rs-api.version>2.1.5</jakarta.ws.rs-api.version>
<license-maven-plugin.version>4.3</license-maven-plugin.version>
<persistence.api.version>2.2.3</persistence.api.version>
<jgit.version>6.4.0.202211300538-r</jgit.version>
<javax.mail.api.version>1.6.4</javax.mail.api.version>
<olingo.version>2.0.13</olingo.version>
<kafka.version>3.3.1</kafka.version>
<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
<mongodb.version>3.12.11</mongodb.version>
<caffeine.version>3.1.2</caffeine.version>
<liquibase-core.version>4.16.1</liquibase-core.version>
<commons-csv.version>1.9.0</commons-csv.version>
<jquery-ui.version>1.13.0</jquery-ui.version>
<sap-theming__theming-base-content.version>11.1.42</sap-theming__theming-base-content.version>
<fundamental-styles.version>0.24.4</fundamental-styles.version>
<angular-aria.version>1.8.2</angular-aria.version>
<split.js.version>1.6.5</split.js.version>
<diff.version>5.1.0</diff.version>
<monaco-editor.version>0.33.0</monaco-editor.version>
<requirejs.version>2.3.6</requirejs.version>
<jstree.version>3.3.12</jstree.version>
<jquery.version>3.6.0</jquery.version>
<jqplot.version>1.0.8r1250</jqplot.version>
<bootstrap.version>3.3.7</bootstrap.version>
<es5-shim.version>4.6.7</es5-shim.version>
<angular-file-upload.version>2.6.1</angular-file-upload.version>
<angularjs.version>1.8.2</angularjs.version>
<fontawesome.version>4.7.0</fontawesome.version>
<classgraph.version>4.8.154</classgraph.version>
<commons-compress.version>1.22</commons-compress.version>
<testcontainers.elasticsearch.version>1.17.6</testcontainers.elasticsearch.version>
<testcontainers.version>1.17.6</testcontainers.version>
<testcontainers.rabbitmq.version>1.17.6</testcontainers.rabbitmq.version>
<amqp.client.version>5.16.0</amqp.client.version>
<elasticsearch.client.version>7.7.1</elasticsearch.client.version>
<jetcd.core.version>0.7.5</jetcd.core.version>
<jetcd.test.version>0.5.4</jetcd.test.version>
<logcaptor.version>2.7.10</logcaptor.version>
<exec.maven.plugin>3.0.0</exec.maven.plugin>
<spring-context-support.version>5.3.24</spring-context-support.version>
<webjars-locator>0.51</webjars-locator>
<keycloak-adapter-bom.version>20.0.2</keycloak-adapter-bom.version>
<hikaricp.version>5.0.1</hikaricp.version>
<validator.version>1.7</validator.version>
<quartz.version>2.3.2</quartz.version>
<c3p0.version>0.9.5.5</c3p0.version>
<graalvm.version>22.3.1</graalvm.version>
<guava.version>31.1-jre</guava.version>
<icu4j.version>72.1</icu4j.version>
<commons-collections.version>3.2.2</commons-collections.version>
<commons-collections4.version>4.4</commons-collections4.version>
<velocity.version>2.3</velocity.version>
<wikitext.version>3.0.45.202211090110</wikitext.version>
<flexmark.version>0.64.0</flexmark.version>
<qldb.driver.version>2.3.1</qldb.driver.version>
<qldb.sdk.version>1.12.386</qldb.sdk.version>
<cassandra.version>1.17.6</cassandra.version>
<cassandra.driver.version>3.11.3</cassandra.driver.version>
<jedis.version>4.3.1</jedis.version>
<spark.version>3.3.1</spark.version>
<path-to-regexp.version>6.2.1</path-to-regexp.version>
<javax.websocket-api.version>1.1</javax.websocket-api.version>
<jacoco.version>0.8.11</jacoco.version>
<jakarta.validation.version>3.0.2</jakarta.validation.version>
<org.springdoc.openapi.ui.version>1.7.0</org.springdoc.openapi.ui.version>
<swagger-annotations.version>1.6.9</swagger-annotations.version>
<profile.content.phase>none</profile.content.phase>
</properties>
</project>
- Navigate to the
applicationfolder. - Open the
pom.xmlfile. -
Make the following changes:
- Navigate to the
<dependencies>section. -
Add the following dependency:
<dependency> <groupId>io.dirigible.samples</groupId> <artifactId>custom-stack-apis</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>
application/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>io.dirigible.samples</groupId> <artifactId>custom-stack-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <name>custom - stack - application</name> <artifactId>custom-stack-application</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <groupId>io.dirigible.samples</groupId> <artifactId>custom-stack-apis</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>io.dirigible.samples</groupId> <artifactId>custom-stack-branding</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <!-- Core --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-core</artifactId> <type>pom</type> <exclusions> <exclusion> <groupId>com.zaxxer</groupId> <artifactId>HikariCP-java7</artifactId> </exclusion> </exclusions> </dependency> <!-- Security --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-security-basic</artifactId> </dependency> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-security-keycloak</artifactId> </dependency> <!-- Data --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-database</artifactId> <type>pom</type> </dependency> <!-- Engine --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-engines</artifactId> <type>pom</type> <exclusions> <exclusion> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> </exclusion> <exclusion> <groupId>org.apache.cxf</groupId> <artifactId> cxf-spring-boot-starter-jaxrs </artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-engine-command</artifactId> </dependency> <!-- IDE --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-ide</artifactId> <type>pom</type> <exclusions> <exclusion> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-ide-ui-branding</artifactId> </exclusion> </exclusions> </dependency> <!-- API --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-api</artifactId> <type>pom</type> </dependency> <!-- Resources --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-resources</artifactId> <type>pom</type> </dependency> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-security-oauth2</artifactId> </dependency> <!-- Templates --> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-components-group-templates</artifactId> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>com.codeborne</groupId> <artifactId>selenide</artifactId> <version>7.2.2</version> <scope>test</scope> </dependency> <!-- Drivers --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-database-mongodb-jdbc</artifactId> </dependency> <dependency> <groupId>com.sap.cloud.db.jdbc</groupId> <artifactId>ngdbc</artifactId> <version>${ngdbc.version}</version> </dependency> <dependency> <groupId>net.snowflake</groupId> <artifactId>snowflake-jdbc</artifactId> <version>${snowflake.version}</version> </dependency> <dependency> <groupId>org.eclipse.dirigible</groupId> <artifactId>dirigible-tests-framework</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>io.dirigible.samples.CustomStackApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!-- Note: Uncomment for git repositories, as this plugin would get the last commit id. This is needed for the info in the "About" view. --> <!-- <plugin> <groupId>pl.project13.maven</groupId> <artifactId>git-commit-id-plugin</artifactId> <version>${git-commit-id-plugin.version}</version> <executions> <execution> <id>get-the-git-infos</id> <goals> <goal>revision</goal> </goals> </execution> </executions> <configuration> <dotGitDirectory>../.git</dotGitDirectory> </configuration> </plugin> --> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> </project> - Navigate to the
Build the Custom Platform
- Navigate to the root folder of the project (e.g.
<my-custom-stack-path>/custom-stack). -
Open the Terminal and execute the following command to build the Custom Platform:
mvn clean install
Run the Custom Platform
- Navigate to the root folder of the project (e.g.
<my-custom-stack-path>/custom-stack). -
Open the Terminal and execute the following command to run the Custom Stack:
java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED -jar application/target/custom-stack-application-*.jar -
Go to http://localhost:8080 to access the Custom Stack.
Test the TypeScript API
- Create a project named
demo-application. - Right click on the
demo-applicationproject and select New → TypeScript CJS Service. - Enter
demo.tsfor the name of the TypeScript Service. -
Replace the content with the following code:
import { response } from "sdk/http"; import { MyApi } from "custom-api/MyApi"; const myApiInstance = new MyApi(); const firstNumber = myApiInstance.add(5, 3); const secondNumber = myApiInstance.multiply(5, 3); const customMethod = myApiInstance.customMethod("tutorial-custom-stack"); const greetingMessage = MyApi.greet(); const data = { firstNumber: firstNumber, secondNumber: secondNumber, customMethod: customMethod, greetingMessage: greetingMessage, }; response.println(JSON.stringify(data, null, 2)); -
Save the changes.
- Right click on the
demo-applicationproject and select New → File. -
Enter
tsconfig.jsonfor the name of the File.{ "compilerOptions": { "module": "ESNext", "target": "ES6", "moduleResolution": "Node", "baseUrl": "../", "lib": [ "ESNext", "DOM" ], "paths": { "sdk/*": [ "../modules/src/*" ], "/*": [ "../*" ] }, "types": [ "../modules/types" ] } } -
Save the changes.
- Right click on the
demo-applicationproject and select New → File. -
Enter
project.jsonfor the name of the File.{ "guid": "demo-application", "actions": [ { "name": "Build TypeScript", "commands": [ { "os": "unix", "command": "tsc" }, { "os": "windows", "command": "cmd /c tsc" } ], "registry": "true" } ] } -
Save the changes.
- Right click on the
demo-applicationproject and select Publish. - Select the
demo.tsfrom the Projects explorer and open the Preview view to see the result.
Next Steps
Section Completed
After completing the steps in this tutorial, you would have:
- APIs Maven Module.
- Java Facade
io.dirigible.samples.MyFacade. - TypeScript API
custom-api/MyApiexposing the Java Facade. - Sample project utilizing the TypeScript API.
Continue either to the the Advanced Facade section or to the Dependency section where external Maven dependency is added and used in the Custom Stack without creating a Java Facade and TypeScript API.
Note: The complete content of the Custom Stack tutorial is available at: https://github.com/dirigiblelabs/tutorial-custom-stack