Commit 9154b2fe authored by Ali Saeed's avatar Ali Saeed

Upload http clien code and http server code with port 8080

parents
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/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="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/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="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
2024-01-17 19:17:49,338 INFO Client.Application [main] Results without headers
2024-01-17 19:17:49,343 INFO Client.Application [main] Server Name: localhost:8080
2024-01-17 19:17:49,343 INFO Client.Application [main] Result of the multiplication is 2000
2024-01-17 19:17:49,344 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,344 INFO Client.Application [main] Server Name: localhost:8080
2024-01-17 19:17:49,344 INFO Client.Application [main] Result of the multiplication is 8641975258917814551662700000000000000
2024-01-17 19:17:49,345 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,345 INFO Client.Application [main] Server Name: localhost:8081
2024-01-17 19:17:49,347 INFO Client.Application [main] Result of the multiplication is 2000
2024-01-17 19:17:49,347 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,347 INFO Client.Application [main] Server Name: localhost:8081
2024-01-17 19:17:49,348 INFO Client.Application [main] Result of the multiplication is 8641975258917814551662700000000000000
2024-01-17 19:17:49,348 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,348 INFO Client.Application [main] Results with headers
2024-01-17 19:17:49,361 INFO Client.Application [main] Server Name: localhost:8080
2024-01-17 19:17:49,362 INFO Client.Application [main] X-Debug-Info : Operation took 126500 ns
2024-01-17 19:17:49,362 INFO Client.Application [main] Result of the multiplication is 2000
2024-01-17 19:17:49,363 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,363 INFO Client.Application [main] Server Name: localhost:8080
2024-01-17 19:17:49,363 INFO Client.Application [main] X-Debug-Info : Operation took 185300 ns
2024-01-17 19:17:49,363 INFO Client.Application [main] Result of the multiplication is 8641975258917814551662700000000000000
2024-01-17 19:17:49,363 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,363 INFO Client.Application [main] Server Name: localhost:8081
2024-01-17 19:17:49,363 INFO Client.Application [main] X-Debug-Info : Operation took 123700 ns
2024-01-17 19:17:49,364 INFO Client.Application [main] Result of the multiplication is 2000
2024-01-17 19:17:49,364 INFO Client.Application [main] ..............................................
2024-01-17 19:17:49,364 INFO Client.Application [main] Server Name: localhost:8081
2024-01-17 19:17:49,364 INFO Client.Application [main] X-Debug-Info : Operation took 163200 ns
2024-01-17 19:17:49,364 INFO Client.Application [main] Result of the multiplication is 8641975258917814551662700000000000000
2024-01-17 19:17:49,364 INFO Client.Application [main] ..............................................
<?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>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
</dependency>
</dependencies>
<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
package Client;
import java.nio.charset.StandardCharsets;
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<ResponseData> sendTasksToWorkers(List<String> workersAddresses, List<String> tasks) {
List<CompletableFuture<ResponseData>> futures = new ArrayList<>();
for (String address : workersAddresses) {
for (String task : tasks) {
byte[] requestPayload = task.getBytes(StandardCharsets.UTF_8);
CompletableFuture<ResponseData> future = webClient.sendTask(address, requestPayload);
futures.add(future);
}
}
return joinFutures(futures);
}
/*send task to list of workers*/
public List<ResponseData> sendTasksToWorkers(List<String> workersAddresses, List<String> tasks, String headers) {
List<CompletableFuture<ResponseData>> futures = new ArrayList<>();
for (String address : workersAddresses) {
for (String task : tasks) {
byte[] requestPayload = task.getBytes(StandardCharsets.UTF_8);
CompletableFuture<ResponseData> future = webClient.sendTask(address, requestPayload, headers);
futures.add(future);
}
}
return joinFutures(futures);
}
private List<ResponseData> joinFutures(List<CompletableFuture<ResponseData>> futures) {
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
try {
allFutures.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
List<ResponseData> results = new ArrayList<>();
for (CompletableFuture<ResponseData> future : futures) {
try {
ResponseData result = future.get();
results.add(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return results;
}
}
package Client;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
private static final String WORKER_ADDRESS_1 = "http://localhost:8080/task";
private static final String WORKER_ADDRESS_2 = "http://localhost:8081/task";
public static void main(String[] args) {
Aggregator aggregator = new Aggregator();
String task1 = "10,200";
String task2 = "123456789,100000000000000,700000002342343";
String headers = "X-Debug: true";
List<ResponseData> results = aggregator.sendTasksToWorkers(Arrays.asList(WORKER_ADDRESS_1, WORKER_ADDRESS_2),
Arrays.asList(task1, task2));
logger.info("Results without headers \n");
for (ResponseData result : results) {
String serverName = result.getServerName();
logger.info("Server Name: " + serverName);
logger.info(result.getBody());
String debugInfo = result.getDebuginfo();
if(debugInfo != null && !debugInfo.isEmpty()){
logger.info("X-Debug-Info : " + debugInfo);
}
logger.info("..............................................");
}
logger.info("Results with headers\n");
List<ResponseData> resultsWithHeaders = aggregator.sendTasksToWorkers(Arrays.asList(WORKER_ADDRESS_1, WORKER_ADDRESS_2),
Arrays.asList(task1, task2), headers);
for (ResponseData result : resultsWithHeaders) {
String serverName = result.getServerName();
logger.info("Server Name: " + serverName);
String debugInfo = result.getDebuginfo();
logger.info("X-Debug-Info : " + debugInfo);
logger.info(result.getBody());
logger.info("..............................................");
}
}
}
package Client;
import java.util.List;
public class ResponseData {
private String body;
private String debugInfo;
private String serverName;
public ResponseData(String body, String debugInfo, String serverName) {
this.body = body;
this.debugInfo = debugInfo;
this.serverName = serverName;
}
public String getServerName() {
return serverName;
}
public String getBody() {
return body;
}
public String getDebuginfo() {
return debugInfo;
}
}
package Client;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
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<ResponseData> sendTask(String url, byte[] requestPayload) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.POST(HttpRequest.BodyPublishers.ofByteArray(requestPayload))
.build();
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(response -> {
HttpHeaders responseHeaders = response.headers();
String body = response.body();
URI uri = response.uri();
String serverName = uri.getHost();
String port = String.valueOf(uri.getPort());
String debugInfo = responseHeaders.firstValue("X-Debug-Info").orElse("");
return new ResponseData(body,debugInfo, serverName+":"+port);
});
}
/* send task (post http request) asynchronously with custom headers*/
public CompletableFuture<ResponseData> sendTask(String url, byte[] requestPayload, String headers) {
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();
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(response -> {
HttpHeaders responseHeaders = response.headers();
String body = response.body();
URI uri = response.uri();
String serverName = uri.getHost();
String port = String.valueOf(uri.getPort());
String debugInfo = responseHeaders.firstValue("X-Debug-Info").orElse("");
return new ResponseData(body,debugInfo, serverName+":"+port);
});
}
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="HOME_LOG" value="logs/app.log"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${HOME_LOG}</file>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</encoder>
</appender>
<!-- Log Level: ERROR, WARN, INFO, DEBUG, TRACE-->
<logger name="Client" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
<root level="error">
<appender-ref ref="FILE"/>
</root>
</configuration>
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/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="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/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="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ 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();
}
}
package org.example;
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 = 8081;
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