All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zaradai.gluon.client.BaseClient Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2017 Zaradai
 * 

* 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 com.zaradai.gluon.client; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.common.util.concurrent.AbstractIdleService; import com.zaradai.gluon.MicroService; import com.zaradai.gluon.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentMap; import static com.google.common.base.Preconditions.checkNotNull; import static com.zaradai.gluon.util.Validations.checkString; public class BaseClient extends AbstractIdleService implements Client { private static final Logger LOG = LoggerFactory.getLogger(BaseClient.class); private final EventBus eventBus; private final ConcurrentMap futureByRequest; private final ConcurrentMap serviceByName; BaseClient(EventBus eventBus) { this.eventBus = checkNotNull(eventBus, "Invalid event bus"); futureByRequest = Maps.newConcurrentMap(); serviceByName = Maps.newConcurrentMap(); eventBus.register(this); } @Override protected void startUp() throws Exception { LOG.info("Client started."); } @Override protected void shutDown() throws Exception { eventBus.unregister(this); LOG.info("Client shutdown."); } @Override public MicroService newService(String serviceName) { final MicroServiceClient res = new MicroServiceClient<>(serviceName, this); // monitor it if (serviceByName.putIfAbsent(serviceName, res) == null) { // send out a request for the service to announce availability eventBus.post(ServiceRequestAnnounce.create(serviceName)); return res; } else { LOG.info("Service: {} already registered! Returning already registered service", serviceName); return serviceByName.get(serviceName); } } protected EventBus getEventBus() { return eventBus; } @VisibleForTesting @Subscribe void handleReply(ServiceReply reply) { LOG.debug("Handling: {}", reply); CompletableFuture future = futureByRequest.remove(reply.getRequestId()); if (future == null) { LOG.debug("Ignoring reply for request: {}", reply.getRequestId()); } else { if (reply.isGood()) { future.complete(reply.getReply()); } else { future.completeExceptionally(reply.getError()); } } } @VisibleForTesting @Subscribe void handleAnnounce(ServiceAnnouncement serviceAnnouncement) { LOG.debug("Handling: {}", serviceAnnouncement); MicroServiceClient microServiceClient = serviceByName.get(serviceAnnouncement.getServiceName()); if (microServiceClient != null) { microServiceClient.setStatus(serviceAnnouncement.getStatus()); } else { LOG.info("Service announcement [{}] for unknown service: {}", serviceAnnouncement.getStatus(), serviceAnnouncement.getServiceName()); } } private CompletableFuture submit(ServiceRequest serviceRequest) { final CompletableFuture future = new CompletableFuture<>(); final String requestId = serviceRequest.getRequestId(); // list for cancellation future.exceptionally((error -> { if (error instanceof CancellationException) { // remove from out monitoring futureByRequest.remove(requestId); // try and kill it remotely eventBus.post(ServiceRequestCancellation.create(requestId)); LOG.info("Sent cancellation for request: {}", requestId); } return null; })); // map future by request futureByRequest.put(requestId, future); // submit the request eventBus.post(serviceRequest); return future; } private static class MicroServiceClient implements MicroService { private final String serviceName; private final BaseClient baseClient; private Status status; private MicroServiceClient(String serviceName, BaseClient baseClient) { this.serviceName = checkString(serviceName, "Service name cannot be null or empty."); this.baseClient = checkNotNull(baseClient, "Kafka client cannot be null."); this.status = Status.CLOSED; } @Override public Status getStatus() { return status; } public MicroServiceClient setStatus(Status status) { this.status = status; return this; } @Override public CompletableFuture apply(Req req) { return baseClient.submit(ServiceRequest.create(serviceName, req)); } @Override public String name() { return serviceName; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy