All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.proofpoint.discovery.ProxyStore Maven / Gradle / Ivy
/*
* Copyright 2013 Proofpoint, Inc.
*
* 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.proofpoint.discovery;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.proofpoint.discovery.client.DiscoveryException;
import com.proofpoint.discovery.client.DiscoveryLookupClient;
import com.proofpoint.discovery.client.HttpDiscoveryLookupClient;
import com.proofpoint.discovery.client.ServiceDescriptor;
import com.proofpoint.discovery.client.ServiceDescriptors;
import com.proofpoint.discovery.client.ServiceDescriptorsRepresentation;
import com.proofpoint.http.client.AsyncHttpClient;
import com.proofpoint.log.Logger;
import com.proofpoint.node.NodeInfo;
import com.proofpoint.units.Duration;
import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.google.common.base.Throwables.propagate;
import static com.proofpoint.discovery.client.announce.DiscoveryAnnouncementClient.DEFAULT_DELAY;
import static com.proofpoint.json.JsonCodec.jsonCodec;
public class ProxyStore
{
private final Set proxyTypes;
private final Map> map;
private static final Logger log = Logger.get(ProxyStore.class);
@Inject
public ProxyStore(final DiscoveryConfig discoveryConfig, Injector injector)
{
this.proxyTypes = discoveryConfig.getProxyProxiedTypes();
if (!proxyTypes.isEmpty()) {
map = new ConcurrentHashMap<>();
AsyncHttpClient httpClient = injector.getInstance(
Key.get(AsyncHttpClient.class, ForProxyStore.class));
DiscoveryLookupClient lookupClient = new HttpDiscoveryLookupClient(
new NodeInfo(discoveryConfig.getProxyEnvironment()),
jsonCodec(ServiceDescriptorsRepresentation.class),
httpClient,
null);
ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(5, new ThreadFactoryBuilder()
.setNameFormat("Proxy-Discovery-%s")
.setDaemon(true)
.build());
for (String type : proxyTypes) {
new ServiceUpdater(type, lookupClient, poolExecutor).start();
}
}
else {
map = null;
}
}
public Set filterAndGetAll(Set services)
{
if (proxyTypes.isEmpty()) {
return services;
}
Builder builder = ImmutableSet.builder();
for (Service service : services) {
if (!proxyTypes.contains(service.getType())) {
builder.add(service);
}
}
for (Set set : map.values()) {
builder.addAll(set);
}
return builder.build();
}
@Nullable
public Set get(String type)
{
if (!proxyTypes.contains(type)) {
return null;
}
return map.get(type);
}
@Nullable
public Set get(String type, final String pool)
{
if (!proxyTypes.contains(type)) {
return null;
}
Builder builder = ImmutableSet.builder();
for (Service service : map.get(type)) {
if (pool.equals(service.getPool())) {
builder.add(service);
}
}
return builder.build();
}
private class ServiceUpdater
{
private final String type;
private final DiscoveryLookupClient lookupClient;
private final ScheduledThreadPoolExecutor poolExecutor;
private final AtomicBoolean serverUp = new AtomicBoolean(true);
public ServiceUpdater(String type, DiscoveryLookupClient lookupClient, ScheduledThreadPoolExecutor poolExecutor)
{
this.type = type;
this.lookupClient = lookupClient;
this.poolExecutor = poolExecutor;
}
public void start()
{
try {
refresh().get(30, TimeUnit.SECONDS);
}
catch (TimeoutException ignored) {
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
if (e.getCause() instanceof DiscoveryException) {
throw (DiscoveryException) e.getCause();
}
throw propagate(e);
}
}
private ListenableFuture refresh()
{
final ListenableFuture future = lookupClient.getServices(type);
future.addListener(new Runnable()
{
@Override
public void run()
{
Duration delay = DEFAULT_DELAY;
try {
ServiceDescriptors descriptors = future.get();
delay = descriptors.getMaxAge();
Builder builder = ImmutableSet.builder();
for (ServiceDescriptor descriptor : descriptors.getServiceDescriptors()) {
builder.add(new Service(
Id.valueOf(descriptor.getId()),
Id.valueOf(descriptor.getNodeId()),
descriptor.getType(),
descriptor.getPool(),
descriptor.getLocation(),
descriptor.getProperties()));
}
map.put(type, builder.build());
if (serverUp.compareAndSet(false, true)) {
log.info("Proxied discovery server connect succeeded for refresh (%s)", type);
}
}
catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
if (!(e.getCause() instanceof DiscoveryException)) {
throw propagate(e);
}
if (serverUp.compareAndSet(true, false)) {
log.error("Cannot connect to proxy discovery server for refresh (%s): %s", type, e.getCause().getMessage());
}
log.debug(e.getCause(), "Cannot connect to proxy discovery server for refresh (%s)", type);
}
finally {
if (!poolExecutor.isShutdown()) {
poolExecutor.schedule(new Runnable()
{
@Override
public void run()
{
refresh();
}
}, (long) delay.toMillis(), TimeUnit.MILLISECONDS);
}
}
}
}, poolExecutor);
return future;
}
}
}