You need to sign in or sign up before continuing.
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