Created base for client implementation
This commit is contained in:
parent
4695dce10d
commit
bde58ef053
@ -12,7 +12,9 @@ repositories {
|
||||
dependencies {
|
||||
implementation project(':client-api')
|
||||
implementation 'org.jetbrains:annotations:24.1.0'
|
||||
implementation 'com.squareup.okhttp:okhttp:2.7.5'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3'
|
||||
|
||||
testImplementation platform('org.junit:junit-bom:5.9.1')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package ru.dragonestia.picker.api.impl;
|
||||
|
||||
import okhttp3.Credentials;
|
||||
import okhttp3.Request;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
|
||||
import ru.dragonestia.picker.api.impl.repository.NodeRepositoryImpl;
|
||||
import ru.dragonestia.picker.api.impl.repository.RoomRepositoryImpl;
|
||||
import ru.dragonestia.picker.api.impl.repository.UserRepositoryImpl;
|
||||
import ru.dragonestia.picker.api.impl.util.RestTemplate;
|
||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
|
||||
public class RoomPickerClient {
|
||||
|
||||
private final String url;
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final RestTemplate restTemplate;
|
||||
private final NodeRepository nodeRepository;
|
||||
private final RoomRepository roomRepository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public RoomPickerClient(@NotNull String url, @NotNull String username, @NotNull String password) {
|
||||
this.url = url;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.restTemplate = new RestTemplate(this);
|
||||
this.nodeRepository = new NodeRepositoryImpl(this);
|
||||
this.roomRepository = new RoomRepositoryImpl(this);
|
||||
this.userRepository = new UserRepositoryImpl(this);
|
||||
}
|
||||
|
||||
@Internal
|
||||
public @NotNull RestTemplate getRestTemplate() {
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public @NotNull Request.Builder prepareRequestBuilder(@NotNull String uri) {
|
||||
return new Request.Builder()
|
||||
.url(url + uri)
|
||||
.addHeader("Authorization", Credentials.basic(username, password));
|
||||
}
|
||||
|
||||
public @NotNull NodeRepository getNodeRepository() {
|
||||
return nodeRepository;
|
||||
}
|
||||
|
||||
public @NotNull RoomRepository getRoomRepository() {
|
||||
return roomRepository;
|
||||
}
|
||||
|
||||
public @NotNull UserRepository getUserRepository() {
|
||||
return userRepository;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package ru.dragonestia.picker.api.impl.repository;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.impl.util.RestTemplate;
|
||||
import ru.dragonestia.picker.api.model.node.INode;
|
||||
import ru.dragonestia.picker.api.model.node.NodeDefinition;
|
||||
import ru.dragonestia.picker.api.repository.NodeRepository;
|
||||
import ru.dragonestia.picker.api.repository.request.node.FindNodeById;
|
||||
import ru.dragonestia.picker.api.repository.request.node.GetAllNodes;
|
||||
import ru.dragonestia.picker.api.repository.request.node.RemoveNodesByIds;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class NodeRepositoryImpl implements NodeRepository {
|
||||
|
||||
private final RestTemplate rest;
|
||||
|
||||
@Internal
|
||||
public NodeRepositoryImpl(RoomPickerClient client) {
|
||||
rest = client.getRestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<INode> allNodes(@NotNull GetAllNodes data) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<INode> findNodeById(@NotNull FindNodeById data) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNodesById(@NotNull RemoveNodesByIds data) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(@NotNull INode node) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNode(@NotNull NodeDefinition definition) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package ru.dragonestia.picker.api.impl.repository;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.impl.util.RestTemplate;
|
||||
import ru.dragonestia.picker.api.model.room.ResponseRoom;
|
||||
import ru.dragonestia.picker.api.model.room.RoomDefinition;
|
||||
import ru.dragonestia.picker.api.model.room.ShortResponseRoom;
|
||||
import ru.dragonestia.picker.api.repository.RoomRepository;
|
||||
import ru.dragonestia.picker.api.repository.request.room.FindRoomById;
|
||||
import ru.dragonestia.picker.api.repository.request.room.GetAllRooms;
|
||||
import ru.dragonestia.picker.api.repository.request.room.RemoveRoomsByIds;
|
||||
import ru.dragonestia.picker.api.repository.type.RoomPath;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class RoomRepositoryImpl implements RoomRepository {
|
||||
|
||||
private final RestTemplate rest;
|
||||
|
||||
@Internal
|
||||
public RoomRepositoryImpl(RoomPickerClient client) {
|
||||
rest = client.getRestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveRoom(@NotNull RoomDefinition definition) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRooms(@NotNull RemoveRoomsByIds request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ShortResponseRoom> allRooms(@NotNull GetAllRooms request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<ResponseRoom> find(@NotNull FindRoomById request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockRoom(@NotNull RoomPath path, boolean value) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package ru.dragonestia.picker.api.impl.repository;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.impl.util.RestTemplate;
|
||||
import ru.dragonestia.picker.api.model.room.ShortResponseRoom;
|
||||
import ru.dragonestia.picker.api.model.user.ResponseUser;
|
||||
import ru.dragonestia.picker.api.repository.UserRepository;
|
||||
import ru.dragonestia.picker.api.repository.request.user.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserRepositoryImpl implements UserRepository {
|
||||
|
||||
private final RestTemplate rest;
|
||||
|
||||
@Internal
|
||||
public UserRepositoryImpl(RoomPickerClient client) {
|
||||
rest = client.getRestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void linkUsersWithRoom(@NotNull LinkUsersWithRoom request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlinkUsersFromRoom(@NotNull UnlinkUsersFromRoom request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ResponseUser> getAllUsersFormRoom(@NotNull GetAllUsersFromRoom request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ResponseUser> searchUsers(@NotNull SearchUsers request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ResponseUser findUserById(@NotNull FindUserById request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ShortResponseRoom> findRoomsLinkedWithUser(@NotNull FindRoomsLinkedWithUser request) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package ru.dragonestia.picker.api.impl.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Response;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import ru.dragonestia.picker.api.exception.ExceptionFactory;
|
||||
import ru.dragonestia.picker.api.impl.RoomPickerClient;
|
||||
import ru.dragonestia.picker.api.impl.util.type.HttpMethod;
|
||||
import ru.dragonestia.picker.api.repository.response.ErrorResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Internal
|
||||
public class RestTemplate {
|
||||
|
||||
private final RoomPickerClient client;
|
||||
private final OkHttpClient httpClient;
|
||||
private final ObjectMapper json;
|
||||
|
||||
public RestTemplate(RoomPickerClient client) {
|
||||
this.client = client;
|
||||
httpClient = new OkHttpClient();
|
||||
json = configureJackson();
|
||||
}
|
||||
|
||||
private ObjectMapper configureJackson() {
|
||||
var mapper = new ObjectMapper();
|
||||
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
|
||||
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
|
||||
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
|
||||
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
|
||||
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
|
||||
return mapper;
|
||||
}
|
||||
|
||||
public void query(String uri, HttpMethod method) {
|
||||
query(uri, method, ParamsConsumer.NONE);
|
||||
}
|
||||
|
||||
public void query(String uri, HttpMethod method, ParamsConsumer paramsConsumer) {
|
||||
var request = client.prepareRequestBuilder(uri + queryEncode(paramsConsumer))
|
||||
.method(method.name(), method == HttpMethod.GET? null : new FormBody.Builder().build())
|
||||
.build();
|
||||
|
||||
try (var response = httpClient.newCall(request).execute()) {
|
||||
checkResponseForErrors(response);
|
||||
} catch (JsonProcessingException ex) {
|
||||
throw new RuntimeException("Json processing error", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T query(String uri, HttpMethod method, Class<T> clazz) {
|
||||
return query(uri, method, clazz, ParamsConsumer.NONE);
|
||||
}
|
||||
|
||||
public <T> T query(String uri, HttpMethod method, Class<T> clazz, ParamsConsumer paramsConsumer) {
|
||||
var request = client.prepareRequestBuilder(uri + queryEncode(paramsConsumer))
|
||||
.method(method.name(), method == HttpMethod.GET? null : new FormBody.Builder().build())
|
||||
.build();
|
||||
|
||||
try (var response = httpClient.newCall(request).execute()) {
|
||||
checkResponseForErrors(response);
|
||||
|
||||
return json.readValue(new String(Objects.requireNonNull(response.body()).bytes(), StandardCharsets.UTF_8), clazz);
|
||||
} catch (JsonProcessingException ex) {
|
||||
throw new RuntimeException("Json processing error", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String queryEncode(ParamsConsumer paramsConsumer) {
|
||||
var params = new HashMap<String, String>();
|
||||
paramsConsumer.accept(params);
|
||||
|
||||
if (params.isEmpty()) return "";
|
||||
|
||||
List<String> pairs = new ArrayList<>();
|
||||
for (var entry: params.entrySet()) {
|
||||
pairs.add(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
|
||||
}
|
||||
return "?" + String.join("&", pairs);
|
||||
}
|
||||
|
||||
private void checkResponseForErrors(Response response) throws IOException {
|
||||
var code = response.code();
|
||||
System.out.println(code);
|
||||
var statusCode = code / 100;
|
||||
|
||||
if (statusCode == 4) {
|
||||
var body = new String(Objects.requireNonNull(response.body()).bytes(), StandardCharsets.UTF_8);
|
||||
throw ExceptionFactory.of(json.readValue(body, ErrorResponse.class));
|
||||
}
|
||||
|
||||
if (statusCode == 5) {
|
||||
throw new RuntimeException("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
public interface ParamsConsumer extends Consumer<Map<String, String>> {
|
||||
|
||||
ParamsConsumer NONE = map -> {};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package ru.dragonestia.picker.api.impl.util.type;
|
||||
|
||||
public enum HttpMethod {
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user