Java tutorial
/* * Copyright 2016 CloudBans (https://cloudbans.xyz) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package xyz.cloudbans.client; import org.apache.http.HttpHeaders; import org.apache.http.HttpRequest; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIUtils; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.protocol.BasicAsyncRequestProducer; import xyz.cloudbans.client.config.ClientConfig; import xyz.cloudbans.client.internal.httpclient.EventCallback; import xyz.cloudbans.client.internal.listener.ReSubscriptionListenerProxy; import xyz.cloudbans.client.listener.EventListener; import xyz.cloudbans.client.response.ban.BanResponse; import xyz.cloudbans.client.response.kick.KickResponse; import xyz.cloudbans.client.response.notice.NoticeResponse; import xyz.cloudbans.client.response.server.ServerHeartbeatResponse; import xyz.cloudbans.client.response.server.ServerPlayerJoinResponse; import xyz.cloudbans.client.response.server.ServerPlayerLeaveResponse; import xyz.cloudbans.client.utils.StringUtils; import xyz.cloudbans.client.utils.httpclient.DeafFutureCallback; import xyz.cloudbans.client.utils.httpclient.SerializerConsumer; import xyz.cloudbans.entities.events.Event; import xyz.cloudbans.entities.events.EventType; import xyz.cloudbans.entities.request.BanRequest; import xyz.cloudbans.entities.request.KickRequest; import xyz.cloudbans.entities.request.NoticeRequest; import xyz.cloudbans.entities.request.ServerHeartbeatRequest; import xyz.cloudbans.entities.request.ServerPlayerJoinRequest; import xyz.cloudbans.entities.request.ServerPlayerLeaveRequest; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.UUID; import java.util.concurrent.Future; public class DefaultClient implements Client { private static final String USER_AGENT = "CloudBans-JavaClient/0.1.0 (see: https://github.com/CloudBans/java-api-client)"; private final HttpAsyncClient client; private final ClientConfig config; public DefaultClient(HttpAsyncClient client, ClientConfig config) { this.client = client; this.config = config; } public HttpAsyncClient getClient() { return client; } @Override public Future<BanResponse> getActiveBan(UUID serverUuid, String playerIdentifier) { HttpGet httpRequest = new HttpGet( buildSafe(createUri("/server/" + serverUuid + "/check/" + escape(playerIdentifier)))); initHeaders(httpRequest); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), BanResponse.class), DeafFutureCallback.<BanResponse>instance()); } @Override public Future<BanResponse> createBan(BanRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/bans"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), BanResponse.class), DeafFutureCallback.<BanResponse>instance()); } @Override public Future<BanResponse> updateBan(BanRequest request) { HttpPut httpRequest = new HttpPut(buildSafe(createUri("/ban/" + request.getId()))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), BanResponse.class), DeafFutureCallback.<BanResponse>instance()); } @Override public Future<BanResponse> deleteBan(UUID banId) { HttpDelete httpRequest = new HttpDelete(buildSafe(createUri("/ban/" + banId))); initHeaders(httpRequest); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), BanResponse.class), DeafFutureCallback.<BanResponse>instance()); } @Override public Future<NoticeResponse> createNotice(NoticeRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/notices"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), NoticeResponse.class), DeafFutureCallback.<NoticeResponse>instance()); } @Override public Future<NoticeResponse> updateNotice(NoticeRequest request) { HttpPut httpRequest = new HttpPut(buildSafe(createUri("/notice/" + request.getId()))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), NoticeResponse.class), DeafFutureCallback.<NoticeResponse>instance()); } @Override public Future<NoticeResponse> deleteNotice(UUID noticeId) { HttpDelete httpRequest = new HttpDelete(buildSafe(createUri("/notice/" + noticeId))); initHeaders(httpRequest); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), NoticeResponse.class), DeafFutureCallback.<NoticeResponse>instance()); } @Override public Future<KickResponse> kick(KickRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/kick"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), KickResponse.class), DeafFutureCallback.<KickResponse>instance()); } @Override public Future<ServerHeartbeatResponse> doHeartbeat(ServerHeartbeatRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/server/heartbeat"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), ServerHeartbeatResponse.class), DeafFutureCallback.<ServerHeartbeatResponse>instance()); } @Override public Future<ServerPlayerJoinResponse> propagateJoin(ServerPlayerJoinRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/server/join"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), ServerPlayerJoinResponse.class), DeafFutureCallback.<ServerPlayerJoinResponse>instance()); } @Override public Future<ServerPlayerLeaveResponse> propagateLeave(ServerPlayerLeaveRequest request) { HttpPost httpRequest = new HttpPost(buildSafe(createUri("/server/leave"))); initHeaders(httpRequest); httpRequest.setEntity(createEntity(request)); return client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), ServerPlayerLeaveResponse.class), DeafFutureCallback.<ServerPlayerLeaveResponse>instance()); } @Override public void registerListener(EventListener listener, EventType... types) { registerOneTimeListener(ReSubscriptionListenerProxy.createReSubscriptionListener(listener, types, this), types); } @Override public void registerOneTimeListener(EventListener listener, EventType... types) { URIBuilder uriBuilder = createUri("/listen").addParameter("types", StringUtils.join(",", (Object[]) types)); HttpGet httpRequest = new HttpGet(buildSafe(uriBuilder)); initHeaders(httpRequest); client.execute(new BasicAsyncRequestProducer(URIUtils.extractHost(config.getBaseUri()), httpRequest), SerializerConsumer.create(config.getSerializer(), Event.class), new EventCallback(listener)); } private URIBuilder createUri(String path) { if (path.startsWith("/")) path = path.substring(1); URI baseUri = config.getBaseUri(); return new URIBuilder(baseUri) .setPath((baseUri.getPath().endsWith("/") ? baseUri.getPath() : baseUri.getPath() + "/") + path); } private StringEntity createEntity(Object body) { return new StringEntity(config.getSerializer().serialize(body), ContentType.APPLICATION_JSON); } private static void initHeaders(HttpRequest request) { request.setHeader(HttpHeaders.USER_AGENT, USER_AGENT); } private static URI buildSafe(URIBuilder builder) { try { return builder.build(); } catch (URISyntaxException e) { throw new RuntimeException("Error occurred while building URI", e); } } private static String escape(String input) { try { return URLEncoder.encode(input, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new UnsupportedOperationException("Cannot encode.", e); } } }