Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework1. Тяпуев Дмитрий. Магистратура. Политех #21

Merged
merged 4 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/main/java/ru/vk/itmo/test/tyapuevdmitrij/ServerImplementation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package ru.vk.itmo.test.tyapuevdmitrij;

import one.nio.http.HttpServer;
import one.nio.http.HttpServerConfig;
import one.nio.http.HttpSession;
import one.nio.http.Param;
import one.nio.http.Path;
import one.nio.http.Request;
import one.nio.http.RequestMethod;
import one.nio.http.Response;
import one.nio.server.AcceptorConfig;
import ru.vk.itmo.ServiceConfig;
import ru.vk.itmo.dao.BaseEntry;
import ru.vk.itmo.dao.Config;
import ru.vk.itmo.dao.Entry;
import ru.vk.itmo.test.tyapuevdmitrij.dao.DAOException;
import ru.vk.itmo.test.tyapuevdmitrij.dao.MemorySegmentDao;

import java.io.IOException;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.nio.charset.StandardCharsets;

public class ServerImplementation extends HttpServer {

private final MemorySegmentDao memorySegmentDao;

private static final String ENTITY_PATH = "/v0/entity";

public ServerImplementation(ServiceConfig config) throws IOException {
super(createServerConfig(config));
memorySegmentDao = new MemorySegmentDao(new Config(config.workingDir(), 5242880));
}

private static HttpServerConfig createServerConfig(ServiceConfig serviceConfig) {
HttpServerConfig serverConfig = new HttpServerConfig();
AcceptorConfig acceptorConfig = new AcceptorConfig();
acceptorConfig.port = serviceConfig.selfPort();
acceptorConfig.reusePort = true;
serverConfig.acceptors = new AcceptorConfig[]{acceptorConfig};
serverConfig.closeSessions = true;
return serverConfig;
}

@Path("/v0/status")
public Response status() {
return Response.ok("OK");
}

@Path(ENTITY_PATH)
@RequestMethod(Request.METHOD_GET)
public Response get(@Param(value = "id", required = true) String id) {
if (id == null || id.isEmpty()) {
return new Response(Response.BAD_REQUEST, Response.EMPTY);
}
MemorySegment key = MemorySegment.ofArray(id.getBytes(StandardCharsets.UTF_8));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

здесь и ниже по коду никак не обрабатываются исключения dao

Entry<MemorySegment> entry = memorySegmentDao.get(key);
if (entry == null) {
return new Response(Response.NOT_FOUND, Response.EMPTY);
}
return Response.ok(entry.value().toArray(ValueLayout.JAVA_BYTE));
}

@Path(ENTITY_PATH)
@RequestMethod(Request.METHOD_PUT)
public Response put(@Param(value = "id", required = true) String id, Request request) {
if (id == null || id.isEmpty()) {
return new Response(Response.BAD_REQUEST, Response.EMPTY);
}
Entry<MemorySegment> entry = new BaseEntry<>(MemorySegment.ofArray(id.getBytes(StandardCharsets.UTF_8)),
MemorySegment.ofArray(request.getBody()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request.getBody() никак не проверяется. Оно может быть null, что, кажется, не совсем ожидается от метода PUT

Такое поведение - это уже DELETE

memorySegmentDao.upsert(entry);
return new Response(Response.CREATED, Response.EMPTY);
}

@Path(ENTITY_PATH)
@RequestMethod(Request.METHOD_DELETE)
public Response delete(@Param(value = "id", required = true) String id) {
if (id == null || id.isEmpty()) {
return new Response(Response.BAD_REQUEST, Response.EMPTY);
}
Entry<MemorySegment> entry = new BaseEntry<>(MemorySegment.ofArray(id.getBytes(StandardCharsets.UTF_8)), null);
memorySegmentDao.upsert(entry);
return new Response(Response.ACCEPTED, Response.EMPTY);
}

public void closeDAO() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

странно, что dao открывает один класс, а закрывает другой. При этом сначала вызывается метод close у server'a, а затем сразу же вызывается метод close у dao.

try {
memorySegmentDao.close();
} catch (IOException e) {
throw new DAOException("can't close DAO", e);
}
}

@Override
public void handleDefault(Request request, HttpSession session) throws IOException {
Response response = new Response(Response.BAD_REQUEST, Response.EMPTY);
session.sendResponse(response);
}

@Path(ENTITY_PATH)
public Response unsupportedMethods() {
return new Response(Response.METHOD_NOT_ALLOWED, Response.EMPTY);
}

}


21 changes: 21 additions & 0 deletions src/main/java/ru/vk/itmo/test/tyapuevdmitrij/ServerStarter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.vk.itmo.test.tyapuevdmitrij;

import ru.vk.itmo.ServiceConfig;

import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

public final class ServerStarter {

private ServerStarter() {

}
public static void main(String[] args) throws IOException {
typuichik123 marked this conversation as resolved.
Show resolved Hide resolved
ServerImplementation server = new ServerImplementation(new ServiceConfig(8080,
"http://localhost",
List.of("http://localhost"),
Files.createTempDirectory(".")));
server.start();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ru.vk.itmo.test.tyapuevdmitrij;

import ru.vk.itmo.ServiceConfig;
import ru.vk.itmo.test.ServiceFactory;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.concurrent.CompletableFuture;

public class ServiceImplementation implements ru.vk.itmo.Service {

private ServerImplementation server;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сначала поля с final, затем уже без final.

private final ServiceConfig config;

public ServiceImplementation(ServiceConfig config) {
this.config = config;
}

@Override
public CompletableFuture<Void> start() throws IOException {
try {
server = new ServerImplementation(config);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
server.start();
return CompletableFuture.completedFuture(null);
}

@Override
public CompletableFuture<Void> stop() throws IOException {
server.stop();
server.closeDAO();
return CompletableFuture.completedFuture(null);
}

@ServiceFactory(stage = 1)
public static class Factory implements ServiceFactory.Factory {

@Override
public ru.vk.itmo.Service create(ServiceConfig config) {
return new ServiceImplementation(config);
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/ru/vk/itmo/test/tyapuevdmitrij/dao/DAOException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ru.vk.itmo.test.tyapuevdmitrij.dao;

public class DAOException extends RuntimeException {
public DAOException(String message, Throwable cause) {
super(message, cause);
}

public DAOException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ru.vk.itmo.test.tyapuevdmitrij.dao;

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.Comparator;

public final class MemorySegmentComparator {
private MemorySegmentComparator() {
throw new IllegalStateException("Utility class");
}

static Comparator<MemorySegment> getMemorySegmentComparator() {
return (segment1, segment2) -> {
long offset = segment1.mismatch(segment2);
if (offset == -1) {
return 0;
}
if (offset == segment1.byteSize()) {
return -1;
}
if (offset == segment2.byteSize()) {
return 1;
}
return segment1.get(ValueLayout.JAVA_BYTE, offset) - segment2.get(ValueLayout.JAVA_BYTE, offset);
};
}
}

Loading
Loading