/* * Copyright 2014 Avanza Bank AB * * 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.avanza.astrix.beans.registry; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.avanza.astrix.beans.core.AstrixBeanKey; import com.avanza.astrix.beans.core.AstrixSettings; import com.avanza.astrix.beans.service.DirectComponent; import com.avanza.astrix.beans.service.ServiceProperties; import com.avanza.astrix.context.AstrixContext; import com.avanza.astrix.context.TestAstrixConfigurer; import com.avanza.astrix.core.ServiceUnavailableException; import com.avanza.astrix.provider.core.AstrixApiProvider; import com.avanza.astrix.provider.core.Service; import com.avanza.astrix.test.util.AstrixTestUtil; public class AstrixServiceRegistryTest { InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry(); TestAstrixConfigurer astrixConfigurer = new TestAstrixConfigurer(); AstrixContext clientContext; @Before public void setup() { astrixConfigurer.registerApiProvider(AstrixServiceRegistryLibraryProvider.class); astrixConfigurer.registerApiProvider(AstrixServiceRegistryServiceProvider.class); } @After public void cleanup() { AstrixTestUtil.closeQuiet(clientContext); } @Test public void serviceRegsistrySupportsMultipleProvidersOfSameService() throws Exception { InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry(); astrixConfigurer.setSubsystem("default"); astrixConfigurer.set(AstrixSettings.SERVICE_REGISTRY_URI, serviceRegistry.getServiceUri()); astrixConfigurer.registerApiProvider(PingApiProvider.class); clientContext = astrixConfigurer.configure(); ServiceRegistryExporterClient server1serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "default", "server-1"); server1serviceRegistryClient.register(Ping.class, DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("1")), Integer.MAX_VALUE); ServiceRegistryExporterClient server2serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "default", "server-2"); server2serviceRegistryClient.register(Ping.class, DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("2")), Integer.MAX_VALUE); Ping ping1 = clientContext.getBean(Ping.class); ServiceRegistryClient serviceRegistryClient = clientContext.getBean(ServiceRegistryClient.class); List<ServiceProperties> providers = serviceRegistryClient.list(AstrixBeanKey.create(Ping.class)); assertEquals(2, providers.size()); assertNotNull(ping1.ping()); } @Test public void doesNotBindToNonPublishedProvidersInOtherZones() throws Exception { InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry(); astrixConfigurer.setSubsystem("default"); astrixConfigurer.set(AstrixSettings.SERVICE_REGISTRY_URI, serviceRegistry.getServiceUri()); astrixConfigurer.registerApiProvider(PingApiProvider.class); clientContext = astrixConfigurer.configure(); ServiceRegistryExporterClient server1serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "my-subsystem", "server-1"); ServiceProperties service1Properties = DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("1")); service1Properties.setProperty(ServiceProperties.PUBLISHED, "false"); service1Properties.setProperty(ServiceProperties.SERVICE_ZONE, "foo-zone"); server1serviceRegistryClient.register(Ping.class, service1Properties, Integer.MAX_VALUE); ServiceRegistryClient serviceRegistryClient = clientContext.getBean(ServiceRegistryClient.class); List<ServiceProperties> providers = serviceRegistryClient.list(AstrixBeanKey.create(Ping.class)); assertEquals(1, providers.size()); Ping ping = clientContext.getBean(Ping.class); try { ping.ping(); fail("Expected service to not be available when server is INACTIVE"); } catch (ServiceUnavailableException e) { // expected } } @Test public void bindsToNonPublishedProvidersInSameZone() throws Exception { InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry(); astrixConfigurer.setSubsystem("my-subsystem"); astrixConfigurer.set(AstrixSettings.SERVICE_REGISTRY_URI, serviceRegistry.getServiceUri()); astrixConfigurer.registerApiProvider(PingApiProvider.class); clientContext = astrixConfigurer.configure(); ServiceRegistryExporterClient server1serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "my-subsystem", "server-1"); ServiceProperties service1Properties = DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("1")); service1Properties.setProperty(ServiceProperties.PUBLISHED, "false"); server1serviceRegistryClient.register(Ping.class, service1Properties, Integer.MAX_VALUE); ServiceRegistryClient serviceRegistryClient = clientContext.getBean(ServiceRegistryClient.class); List<ServiceProperties> providers = serviceRegistryClient.list(AstrixBeanKey.create(Ping.class)); assertEquals(1, providers.size()); Ping ping = clientContext.getBean(Ping.class); assertNotNull(ping.ping()); } @Test public void usesRoundRobinToDistributeConsumers() throws Exception { InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry(); astrixConfigurer.set(AstrixSettings.SERVICE_REGISTRY_URI, serviceRegistry.getServiceUri()); astrixConfigurer.registerApiProvider(PingApiProvider.class); clientContext = astrixConfigurer.configure(); ServiceRegistryExporterClient server1serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "default", "server-1"); ServiceProperties service1Properties = DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("1")); server1serviceRegistryClient.register(Ping.class, service1Properties, Integer.MAX_VALUE); ServiceRegistryExporterClient server2serviceRegistryClient = new ServiceRegistryExporterClient(serviceRegistry, "default", "server-2"); ServiceProperties service2Properties = DirectComponent.registerAndGetProperties(Ping.class, new PingImpl("1")); server2serviceRegistryClient.register(Ping.class, service2Properties, Integer.MAX_VALUE); ServiceRegistryClient serviceRegistryClient = clientContext.getBean(ServiceRegistryClient.class); int server1ConsumerCount = 0; int server2ConsumerCount = 0; for (int i = 0; i < 10; i++) { ServiceProperties props = serviceRegistryClient.lookup(AstrixBeanKey.create(Ping.class)); if ("server-1".equals(props.getProperty(ServiceProperties.APPLICATION_INSTANCE_ID))) { server1ConsumerCount++; } if ("server-2".equals(props.getProperty(ServiceProperties.APPLICATION_INSTANCE_ID))) { server2ConsumerCount++; } } assertEquals(5, server1ConsumerCount); assertEquals(5, server2ConsumerCount); } @AstrixApiProvider public interface PingApiProvider { @Service Ping ping(); } public interface Ping { String ping(); } public class PingImpl implements Ping { private String id; public PingImpl(String id) { this.id = id; } @Override public String ping() { return id; } } }