Commit 7afa65cc authored by mohammad.salama's avatar mohammad.salama

Working Client-Server no jars yet and no logging

parents
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="httpclient" />
<module name="httpserver" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="httpclient" target="17" />
<module name="httpserver" target="9" />
</bytecodeTargetLevel>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/httpclient/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/httpclient/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/httpclient/pom.xml" />
<option value="$PROJECT_DIR$/httpserver/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17 (2)" project-jdk-type="JavaSDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/httpclient/httpclient.iml" filepath="$PROJECT_DIR$/httpclient/httpclient.iml" />
<module fileurl="file://$PROJECT_DIR$/httpserver/httpserver.iml" filepath="$PROJECT_DIR$/httpserver/httpserver.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/network-communication.iml" filepath="$PROJECT_DIR$/.idea/network-communication.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_17">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.example</groupId>
<artifactId>httpclient</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
\ No newline at end of file
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class Aggregator {
private WebClient webClient;
public Aggregator() {
this.webClient = new WebClient();
}
/*send task to list of workers*/
public List<String> sendTasksToWorkers(List<String> workersAddresses, List<String> tasks) throws ExecutionException, InterruptedException {
List<String> responses = new ArrayList<>();
List<CompletableFuture<String>> temp = new ArrayList<>();
for (String workerAddr : workersAddresses)
{
for (String task : tasks)
{
temp.add(webClient.sendTask(workerAddr , task.getBytes()));
}
}
for (CompletableFuture<String> resp : temp)
{
responses.add(resp.get());
}
//throw new UnsupportedOperationException();
return responses;
}
/*send task to list of workers*/
public List<String> sendTasksToWorkers(List<String> workersAddresses, List<String> tasks, String headers) throws ExecutionException, InterruptedException {
List<String> responses = new ArrayList<>();
List<CompletableFuture<String>> temp = new ArrayList<>();
for (String workerAddr : workersAddresses)
{
for (String task : tasks)
{
temp.add(webClient.sendTask(workerAddr , task.getBytes() , headers));
}
}
for (CompletableFuture<String> resp : temp)
{
responses.add(resp.get());
}
return responses;
}
}
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class Application {
private static final String WORKER_ADDRESS_1 = "http://localhost:8080/task";
private static final String WORKER_ADDRESS_2 = "http://localhost:8080/task";
public static void main(String[] args) throws ExecutionException, InterruptedException {
Aggregator aggregator = new Aggregator();
String task1 = "10,200";
String task2 = "123456789,100000000000000,700000002342343";
String headers = "X-Debug: true";
List<String> results = aggregator.sendTasksToWorkers(Arrays.asList(WORKER_ADDRESS_1, WORKER_ADDRESS_2),
Arrays.asList(task1, task2));
for (String result : results) {
System.out.println(result);
}
List<String> resultsWithHeaders = aggregator.sendTasksToWorkers(Arrays.asList(WORKER_ADDRESS_1, WORKER_ADDRESS_2),
Arrays.asList(task1, task2), headers);
for (String result : resultsWithHeaders) {
System.out.println(result);
}
}
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class WebClient {
private HttpClient client;
/* instantiate web client */
/* Read more about Builder pattern https://en.wikipedia.org/wiki/Builder_pattern*/
public WebClient()
{
this.client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build();
}
/* send task (post http request) asynchronously */
public CompletableFuture<String> sendTask(String url, byte[] requestPayload)
{
CompletableFuture<String> response = new CompletableFuture<>();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(url))
.POST(HttpRequest.BodyPublishers.ofByteArray(requestPayload))
.build();
response = client.sendAsync
(httpRequest ,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)).
thenApply(HttpResponse::body);
return response;
}
/* send task (post http request) asynchronously with custom headers*/
public CompletableFuture<String> sendTask(String url, byte[] requestPayload, String headers)
{
CompletableFuture<String> response = new CompletableFuture<>();
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(url))
.POST(HttpRequest.BodyPublishers.ofByteArray(requestPayload));
if (headers != null && !headers.isEmpty())
{
String[] headerLines = headers.split("\n");
for (String headerLine : headerLines)
{
String[] headerParts = headerLine.split(":");
String headerName = headerParts[0].trim();
String headerValue = headerParts[1].trim();
requestBuilder.header(headerName, headerValue);
}
}
HttpRequest request = requestBuilder.build();
response = client.sendAsync
(request,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
.thenApply(HttpResponse::body);
return response;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_9">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.example</groupId>
<artifactId>httpserver</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
import com.sun.net.httpserver.*;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
public class WebServer
{
static final Logger logger = Logger.getLogger("WebServer");
private static final String TASK_ENDPOINT = "/task";
private static final String Status_ENDPOINT = "/status";
private final int port;
private HttpServer server;
public WebServer(int port) {
this.port = port;
}
public static void main(String[] args) {
int serverPort = 8080;
if (args.length == 1) {
serverPort = Integer.parseInt(args[0]);
}
WebServer webServer = new WebServer(serverPort);
webServer.startServer();
System.out.println("Server is listening on port " + serverPort);
}
public void startServer() {
try {
this.server = HttpServer.create(new InetSocketAddress(port), 0);
} catch (IOException e) {
throw new RuntimeException(e);
}
HttpContext statusContext = server.createContext(Status_ENDPOINT);
HttpContext taskContext = server.createContext(TASK_ENDPOINT);
statusContext.setHandler(this::handleStatusCheckRequest);
taskContext.setHandler(this::handleTaskRequest);
server.setExecutor(Executors.newFixedThreadPool(8));
server.start();
}
private void handleTaskRequest(HttpExchange exchange) throws IOException {
if (!exchange.getRequestMethod().equalsIgnoreCase("post")) {
exchange.close();
return;
}
Headers headers = exchange.getRequestHeaders();
if (headers.containsKey("X-Test") && headers.get("X-Test").get(0).equalsIgnoreCase("true")) {
String dummyResp = "123\n";
sendResponse(dummyResp.getBytes(), exchange);
return;
}
boolean isDebugMode = false;
if (headers.containsKey("X-Debug") && headers.get("X-Debug").get(0).equalsIgnoreCase("true")) {
isDebugMode = true;
}
long startTime = System.nanoTime();
byte[] requestBytes = exchange.getRequestBody().readAllBytes();
byte[] responseBytes = calculateResponse(requestBytes);
long finishTime = System.nanoTime();
if (isDebugMode) {
String debugMessage = String.format("Operation took %d ns", finishTime - startTime);
exchange.getResponseHeaders().put("X-Debug-Info", Arrays.asList(debugMessage));
}
sendResponse(responseBytes, exchange);
}
private byte[] calculateResponse(byte[] requestBytes) {
String bodyString = new String(requestBytes);
String[] stringNumbers = bodyString.split(",");
BigInteger result = BigInteger.ONE;
for (String number : stringNumbers) {
BigInteger bigInteger = new BigInteger(number);
result = result.multiply(bigInteger);
}
return String.format("Result of the multiplication is %s\n", result).getBytes();
}
private void handleStatusCheckRequest(HttpExchange exchange) throws IOException {
if (!exchange.getRequestMethod().equalsIgnoreCase("get")) {
exchange.close();
return;
}
String responseMessage = "Server is alive\n";
sendResponse(responseMessage.getBytes(), exchange);
}
private void sendResponse(byte[] responseBytes, HttpExchange exchange) throws IOException {
exchange.sendResponseHeaders(200, responseBytes.length);
OutputStream outputStream = exchange.getResponseBody();
outputStream.write(responseBytes);
outputStream.flush();
outputStream.close();
exchange.close();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment