Share
Explore

Building the Distributed IT Application with Java API calls (Remote Method Invocation)

megaphone

PowerShell Script to terminate ghost server processes:


$Port = 8080 $Process = Get-NetTCPConnection -LocalPort $Port | Select-Object -Property OwningProcess -Unique Stop-Process -Id $Process.OwningProcess -Force

Introductory lecture covering REST and Spring: Spring is a framework for building REST applications, along with examples of some verticals where API calls might be useful.
Spring is a WEB Services Framework. Spring is a set of Java Libraries for building Distributed System. This discussion is also applicable to EDGE Computing.
REST = Representational State Transfer: REST is a protocol for doing remote method invocation: RMI
Since the Internet became available to commercial public use in 1992 for business applications, we wanted to exchange services over the Internet.
REMEMBER: A Service is JUST A METHOD CALL, being called on a Java Object that lives in another JVM (java.exe), on a Java Object that we access over TCP/IP.
Watch my Video on Service Oriented Architectures:

Introduction to REST and Spring (Spring is a Framework for doing REST)

Doing Remote Method Invocation: What is REST?

REST, or Representational State Transfer, is an architectural style for distributed systems.
REST is often used in web services development to create robust, scalable, and maintainable services.
REST is a way of doing RMI Remote method invocation calls over an HTTP Stream running on a TCP Pipe.
Here's a brief overview:
Stateless: Each request from a client to a server must contain all the information needed to understand and process the request.
Client-Server Architecture: Clients and servers interact but remain independent, allowing each to be developed and enhanced separately.
Uniform Interface: RESTful systems provide a consistent set of standard conventions (like using HTTP methods GET, POST, PUT, DELETE) to perform actions on resources, which are represented by URLs.

What is Spring?

Spring is a comprehensive framework for building enterprise-grade applications in Java. One of its many projects, Spring Boot, simplifies the process of building production-ready applications by providing sensible defaults and reducing boilerplate code. Spring's features include:
Dependency Injection: Allows defining dependencies between objects, making code more maintainable and testable. Dependency Injection is done with the @symbol notation. Essentially, @ dependency injection means grabbing some code from another class and shoving it into our current class.
Aspect-Oriented Programming (AOP): Enables defining cross-cutting concerns, such as logging and security, separately from business logic. To understand AOP, remember that the purpose of an object is to model an entity in our Business Domain (Business Objects: make business processes come to life and run in our Java Application.)
What about activities like logging program execution details to a text file: This is an ASPECT of the system operation that might cross cut across many classes (cross-cutting concern) - NOT a business domain activity to be modeled. In the case of what we are doing here: We are connecting Java Objects with an HTTP connection stream running in a TCP Pipe. The purpose of this connection is to allow remote remote method invocation.
Spring MVC: A framework for building web applications, including RESTful web services. RESTful web services just means we are connecting Java Objects over an HTTP stream.

Examples of Useful Verticals of API Calls

APIs are essential in various industries for facilitating the integration and interaction of different systems. Here are examples of verticals where API calls are utilized:
Healthcare:
Electronic Health Records (EHRs): APIs can enable integration between different EHR systems, allowing healthcare providers to access patient data across platforms.
Telemedicine Services: APIs can facilitate video conferencing and real-time data sharing between doctors and patients.
Finance:
Payment Gateways: APIs are used to process online transactions, linking merchants, banks, and payment processors.
Investment Platforms: APIs can provide access to real-time stock market data and facilitate automated trading.
Travel and Hospitality:
Booking Platforms: Travel websites use APIs to aggregate information on flights, hotels, and car rentals from various providers.
Weather Services: Travel apps can integrate weather APIs to provide travelers with up-to-date forecasts. For example, OpenWeather API.
Retail and E-commerce:
Product Catalogs: APIs allow retailers to share their product catalogs with partner platforms, such as online marketplaces.
Shipping Services: E-commerce platforms can integrate shipping providers' APIs to calculate shipping costs and track packages.
Education:
Learning Management Systems (LMS): APIs enable the integration of various educational tools and content providers within an LMS.
Library Systems: Educational institutions can use APIs to provide access to digital libraries and research databases.

Conclusion

REST and Spring form a powerful combination for building robust and scalable web services. The principles of REST help in creating a clean and standardized interface, while Spring offers a comprehensive set of tools to implement such services.
The examples of verticals demonstrate the wide-ranging applicability of APIs in various domains, from healthcare to education, underlining their importance in modern software architecture.
Below you will find a simple Java application composed of two classes. One is the TemperatureServiceProvider class that contains a method to convert Celsius to Fahrenheit. The other is the TemperatureConsumer class, which utilizes the service to perform a temperature conversion.

TemperatureServiceProvider.java

This class provides a method to convert temperature from Celsius to Fahrenheit.

public class TemperatureServiceProvider {

// Method to convert Celsius to Fahrenheit
public double celsiusToFahrenheit(double celsius) {
return (celsius * 9/5) + 32;
}
}

TemperatureConsumer.java

This class consumes the TemperatureServiceProvider to perform a temperature conversion.

public class TemperatureConsumer {

public static void main(String[] args) {
// Create an instance of the service provider class
TemperatureServiceProvider serviceProvider = new TemperatureServiceProvider();

// Example temperature in Celsius
double celsius = 25.0;

// Use the service to convert Celsius to Fahrenheit
double fahrenheit = serviceProvider.celsiusToFahrenheit(celsius);

// Print the result
System.out.println(celsius + "°C is equal to " + fahrenheit + "°F");
}
}

When you run the TemperatureConsumer class, it will print the conversion result to the console.
This code provides a clean separation between the service provider and consumer, making it straightforward to later integrate RESTful service calls or any other communication mechanisms.

A simple Java application code showing 2 classes:
a service provider class that converts celsius to farenheit
a cosumer class that calls the service class.
This does NOT yet use REST api calls - we will do that in the next activity:

Below you will find a simple Java application composed of two classes.
One is the TemperatureServiceProvider class that contains a method to convert Celsius to Fahrenheit. The other is the TemperatureConsumer class, which utilizes the service to perform a temperature conversion.

TemperatureServiceProvider.java

This class provides a method to convert temperature from Celsius to Fahrenheit.
javaCopy code
public class TemperatureServiceProvider {

// Method to convert Celsius to Fahrenheit
public double celsiusToFahrenheit(double celsius) {
return (celsius * 9/5) + 32;
}
}

TemperatureConsumer.java

This class consumes the TemperatureServiceProvider to perform a temperature conversion.
javaCopy code
public class TemperatureConsumer {

public static void main(String[] args) {
// Create an instance of the service provider class
TemperatureServiceProvider serviceProvider = new TemperatureServiceProvider();

// Example temperature in Celsius
double celsius = 25.0;

// Use the service to convert Celsius to Fahrenheit
double fahrenheit = serviceProvider.celsiusToFahrenheit(celsius);

// Print the result
System.out.println(celsius + "°C is equal to " + fahrenheit + "°F");
}
}

When you run the TemperatureConsumer class, it will print the conversion result to the console.
This code provides a clean separation between the service provider and consumer, making it straightforward to later integrate RESTful service calls or any other communication mechanisms.
Now present this application with REST api calls.
Keep it very simple and introductory and do not use spring framework or maven, yet. That is coming next.
We can transform the application into a simple RESTful service by using the built-in Java libraries for Network Sockets to allow Remote Method Invocation without Spring or Maven.

Simplest Web Services Application (NOT YET with REST Calls)

We'll use a basic HTTP server provided by the com.sun.net.httpserver package. (This is the simplest building block to create Java Web Services).

TemperatureServiceProvider.java

This class will now include the HTTP server setup to handle requests.
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class TemperatureServiceProvider {

public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/celsiusToFahrenheit", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
System.out.println("Server started on port 8080");
}

static class MyHandler implements HttpHandler {
@Override
public void handle(com.sun.net.httpserver.HttpExchange t) throws IOException {
String query = t.getRequestURI().getQuery();
System.out.println("Query: " + query); // Debugging print statement

// Handling the case where the query is null (e.g., incorrect URL)
if (query == null || !query.startsWith("temp=")) {
String response = "Invalid request";
t.sendResponseHeaders(400, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
return;
}

String[] params = query.split("=");
double celsius = Double.parseDouble(params[1]);

double fahrenheit = (celsius * 9/5) + 32;
String response = celsius + "°C is equal to " + fahrenheit + "°F";
System.out.println("Response: " + response); // Debugging print statement

t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}

TemperatureConsumer.java

This class will now make an HTTP GET request to the service.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

public class TemperatureConsumer {

public static void main(String[] args) {
try {
// Prompt the user to enter a temperature in Celsius
Scanner scanner = new Scanner(System.in);
System.out.print("Please enter the temperature in Celsius: ");
double celsius = scanner.nextDouble();

// Construct the URL
String url = "http://localhost:8080/celsiusToFahrenheit?temp=" + celsius;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();

// Get the response code
int responseCode = con.getResponseCode();

// Read the response
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

// Print the result
System.out.println(response.toString());

// Keep the terminal window open by waiting for the user to press Enter
System.out.println("Press Enter to exit...");
scanner.nextLine(); // Consume the remaining newline
scanner.nextLine(); // Wait for the user to press Enter
} catch (Exception e) {
e.printStackTrace();
}
}
}


Add a few more features:


megaphone

We can modify the TemperatureConsumer class to prompt the user for temperature input at the command line. Here's the updated code:


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

public class TemperatureConsumer {

public static void main(String[] args) throws Exception {
// Create a Scanner object to read input from the command line
Scanner scanner = new Scanner(System.in);

// Prompt the user for temperature input in Celsius
System.out.print("Please enter the temperature in Celsius: ");
double celsius = scanner.nextDouble();

// Construct the URL with the entered temperature
String url = "http://localhost:8080/celsiusToFahrenheit?temp=" + celsius;

URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();

// Optional default is GET
con.setRequestMethod("GET");

int responseCode = con.getResponseCode();

BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

// Print the result
System.out.println(response.toString());

// Close the scanner
scanner.close();
}
}

When you run the updated TemperatureConsumer class, it will prompt you to enter a temperature in Celsius and then print the converted value in Fahrenheit. Make sure that the TemperatureServiceProvider class is running and listening on the correct port before running the consumer class.
image.png


Make sure to start the TemperatureServiceProvider first and then run the TemperatureConsumer to see the result printed to the console.
Note that the com.sun.net.httpserver package is specific to the Oracle JDK, so this code might not work with other Java distributions. In a real-world scenario, it would be more common to use a framework like Spring or a library like Jetty or Tomcat for handling HTTP, but this code gives you a simple, raw introduction to how you might set up a RESTful service and consumer in plain Java.

Part 1: Was both classes running in the Same JVM.

Part 2: Was producer and consumer running in separate JVMs and connecting through TCP IP using Java Net Socket Class.


Part 3: Connect Producer and Consumer using REST API Calls:

In Part 3 of this lab, we'll modify the producer and consumer applications to communicate via REST API calls. We'll keep everything simple and without frameworks like Spring for now.

Part 3: Connecting Producer and Consumer via REST API

3.1 Overview

REST (Representational State Transfer) is an architectural pattern for building distributed Java web applications. It a set of principles for building web services. In a RESTful system, resources (such as temperature conversion) are accessed via standard HTTP methods, such as GET and POST, over an HTTP stream.
We'll modify our producer (server) to handle HTTP requests for temperature conversion and our consumer (client) to make HTTP requests to the producer's REST endpoint.

Producer (Server) - RESTful Service

The producer code provided in previous parts already implements a simple HTTP server and a RESTful endpoint for temperature conversion. It exposes a Remote Method Invocation - a HTTP GET method at http://localhost:8080/celsiusToFahrenheit and takes a query parameter named temp for the temperature in Celsius.
Here's the code snippet again for reference:
public static class MyHandler implements HttpHandler {
@Override
public void handle(com.sun.net.httpserver.HttpExchange t) throws IOException {
String query = t.getRequestURI().getQuery();
String[] params = query.split("=");
double celsius = Double.parseDouble(params[1]);
double fahrenheit = (celsius * 9/5) + 32;
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.