xyz.cloudbans.client.DefaultClient.java Source code

Java tutorial

Introduction

Here is the source code for xyz.cloudbans.client.DefaultClient.java

Source

/*
 * 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);
        }
    }
}