/*
* Copyright 2010 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 io.airlift.discovery.client.testing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapMaker;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import io.airlift.discovery.client.DiscoveryAnnouncementClient;
import io.airlift.discovery.client.DiscoveryException;
import io.airlift.discovery.client.DiscoveryLookupClient;
import io.airlift.discovery.client.ServiceAnnouncement;
import io.airlift.discovery.client.ServiceDescriptor;
import io.airlift.discovery.client.ServiceDescriptors;
import io.airlift.node.NodeInfo;
import io.airlift.units.Duration;
import javax.inject.Inject;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import static java.util.Objects.requireNonNull;
public class InMemoryDiscoveryClient implements DiscoveryAnnouncementClient, DiscoveryLookupClient
{
private final AtomicReference<Set<ServiceDescriptor>> announcements = new AtomicReference<Set<ServiceDescriptor>>(ImmutableSet.<ServiceDescriptor>of());
private final ConcurrentMap<UUID, ServiceDescriptor> discovered = new MapMaker().makeMap();
private final NodeInfo nodeInfo;
private final Duration maxAge;
@Inject
public InMemoryDiscoveryClient(NodeInfo nodeInfo)
{
requireNonNull(nodeInfo, "nodeInfo is null");
this.nodeInfo = nodeInfo;
maxAge = DEFAULT_DELAY;
}
public InMemoryDiscoveryClient(NodeInfo nodeInfo, Duration maxAge)
{
requireNonNull(nodeInfo, "nodeInfo is null");
requireNonNull(maxAge, "maxAge is null");
this.nodeInfo = nodeInfo;
this.maxAge = maxAge;
}
public ServiceDescriptor addDiscoveredService(ServiceDescriptor serviceDescriptor)
{
requireNonNull(serviceDescriptor, "serviceDescriptor is null");
return discovered.put(serviceDescriptor.getId(), serviceDescriptor);
}
public ServiceDescriptor remove(UUID uuid)
{
requireNonNull(uuid, "uuid is null");
return discovered.remove(uuid);
}
@Override
public CheckedFuture<Duration, DiscoveryException> announce(Set<ServiceAnnouncement> services)
{
requireNonNull(services, "services is null");
ImmutableSet.Builder<ServiceDescriptor> builder = ImmutableSet.builder();
for (ServiceAnnouncement service : services) {
builder.add(service.toServiceDescriptor(nodeInfo));
}
announcements.set(builder.build());
return Futures.immediateCheckedFuture(maxAge);
}
@Override
public CheckedFuture<Void, DiscoveryException> unannounce()
{
announcements.set(ImmutableSet.<ServiceDescriptor>of());
return Futures.immediateCheckedFuture(null);
}
@Override
public CheckedFuture<ServiceDescriptors, DiscoveryException> getServices(String type)
{
requireNonNull(type, "type is null");
ImmutableList.Builder<ServiceDescriptor> builder = ImmutableList.builder();
for (ServiceDescriptor serviceDescriptor : this.announcements.get()) {
if (serviceDescriptor.getType().equals(type)) {
builder.add(serviceDescriptor);
}
}
for (ServiceDescriptor serviceDescriptor : this.discovered.values()) {
if (serviceDescriptor.getType().equals(type)) {
builder.add(serviceDescriptor);
}
}
return Futures.immediateCheckedFuture(new ServiceDescriptors(type, null, builder.build(), maxAge, UUID.randomUUID().toString()));
}
@Override
public CheckedFuture<ServiceDescriptors, DiscoveryException> getServices(String type, String pool)
{
requireNonNull(type, "type is null");
requireNonNull(pool, "pool is null");
ImmutableList.Builder<ServiceDescriptor> builder = ImmutableList.builder();
for (ServiceDescriptor serviceDescriptor : this.announcements.get()) {
if (serviceDescriptor.getType().equals(type) && serviceDescriptor.getPool().equals(pool)) {
builder.add(serviceDescriptor);
}
}
for (ServiceDescriptor serviceDescriptor : this.discovered.values()) {
if (serviceDescriptor.getType().equals(type) && serviceDescriptor.getPool().equals(pool)) {
builder.add(serviceDescriptor);
}
}
return Futures.immediateCheckedFuture(new ServiceDescriptors(type, pool, builder.build(), maxAge, UUID.randomUUID().toString()));
}
@Override
public CheckedFuture<ServiceDescriptors, DiscoveryException> refreshServices(ServiceDescriptors serviceDescriptors)
{
requireNonNull(serviceDescriptors, "serviceDescriptors is null");
return getServices(serviceDescriptors.getType(), serviceDescriptors.getPool());
}
}