-
Notifications
You must be signed in to change notification settings - Fork 48
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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)); | ||
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())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
} | ||
|
||
} | ||
|
||
|
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
} | ||
} | ||
} |
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); | ||
}; | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
здесь и ниже по коду никак не обрабатываются исключения dao