/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.sling.discovery.base.connectors.announcement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.List; import java.util.UUID; import javax.jcr.Session; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.commons.testing.jcr.RepositoryProvider; import org.apache.sling.commons.testing.junit.categories.Slow; import org.apache.sling.discovery.ClusterView; import org.apache.sling.discovery.InstanceDescription; import org.apache.sling.discovery.base.connectors.BaseConfig; import org.apache.sling.discovery.base.its.setup.TopologyHelper; import org.apache.sling.discovery.base.its.setup.VirtualInstanceHelper; import org.apache.sling.discovery.base.its.setup.mock.MockFactory; import org.apache.sling.discovery.base.its.setup.mock.SimpleConnectorConfig; import org.apache.sling.discovery.commons.providers.DefaultClusterView; import org.apache.sling.discovery.commons.providers.DefaultInstanceDescription; import org.apache.sling.discovery.commons.providers.spi.base.DummySlingSettingsService; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; public class AnnouncementRegistryImplTest { private AnnouncementRegistryImpl registry; private String slingId; private ResourceResolverFactory resourceResolverFactory; private BaseConfig config; @Before public void setup() throws Exception { resourceResolverFactory = MockFactory .mockResourceResolverFactory(); config = new SimpleConnectorConfig() { public long getConnectorPingTimeout() { // 10s for tests that also run on apache jenkins return 10; }; }; slingId = UUID.randomUUID().toString(); Session l = RepositoryProvider.instance().getRepository() .loginAdministrative(null); try { l.removeItem("/var"); l.save(); l.logout(); } catch (Exception e) { l.refresh(false); l.logout(); } registry = AnnouncementRegistryImpl.testConstructorAndActivate( resourceResolverFactory, new DummySlingSettingsService(slingId), config); } @Test public void testRegisterUnregister() throws Exception { doTestRegisterUnregister(false); } @Category(Slow.class) @Test public void testRegisterUnregister_Slow() throws Exception { doTestRegisterUnregister(true); } private void doTestRegisterUnregister(boolean includeFinalExpiryCheck) throws Exception { try{ registry.registerAnnouncement(null); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } try{ registry.unregisterAnnouncement(null); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } try{ registry.unregisterAnnouncement(""); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } try{ new Announcement(null); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } try{ new Announcement(""); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } Announcement ann = new Announcement(slingId); assertFalse(ann.isValid()); assertFalse(registry.registerAnnouncement(ann)!=-1); DefaultClusterView localCluster = new DefaultClusterView(UUID.randomUUID().toString()); ann.setLocalCluster(localCluster); assertFalse(ann.isValid()); assertFalse(registry.registerAnnouncement(ann)!=-1); try{ registry.listInstances(localCluster); fail("doing getInstances() on an empty cluster should throw an illegalstateexception"); } catch(IllegalStateException ise) { // ok } DefaultInstanceDescription instance = TopologyHelper.createInstanceDescription(ann.getOwnerId(), true, localCluster); assertEquals(instance.getSlingId(), ann.getOwnerId()); assertTrue(ann.isValid()); assertTrue(registry.registerAnnouncement(ann)!=-1); assertEquals(1, registry.listInstances(localCluster).size()); registry.checkExpiredAnnouncements(); assertEquals(1, registry.listInstances(localCluster).size()); registry.unregisterAnnouncement(ann.getOwnerId()); assertEquals(0, registry.listInstances(localCluster).size()); assertTrue(ann.isValid()); assertTrue(registry.registerAnnouncement(ann)!=-1); assertEquals(1, registry.listInstances(localCluster).size()); if (includeFinalExpiryCheck) { Thread.sleep(10500); assertEquals(0, registry.listInstances(localCluster).size()); } } @Test public void testLists() throws Exception { try{ registry.listAnnouncementsInSameCluster(null); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } try{ registry.listAnnouncementsInSameCluster(null); fail("should complain"); } catch(IllegalArgumentException iae) { // ok } assertEquals(0, registry.listLocalAnnouncements().size()); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); DefaultClusterView localCluster = new DefaultClusterView(UUID.randomUUID().toString()); DefaultInstanceDescription instance = TopologyHelper.createInstanceDescription(slingId, true, localCluster); assertEquals(0, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(0, registry.listLocalAnnouncements().size()); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); Announcement ann = new Announcement(slingId); ann.setLocalCluster(localCluster); ann.setInherited(true); registry.registerAnnouncement(ann); assertEquals(1, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(1, registry.listLocalAnnouncements().size()); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); ann.setInherited(true); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); assertTrue(registry.hasActiveAnnouncement(slingId)); assertFalse(registry.hasActiveAnnouncement(UUID.randomUUID().toString())); registry.unregisterAnnouncement(slingId); assertEquals(0, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(0, registry.listLocalAnnouncements().size()); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); assertFalse(registry.hasActiveAnnouncement(slingId)); assertFalse(registry.hasActiveAnnouncement(UUID.randomUUID().toString())); ann.setInherited(false); registry.registerAnnouncement(ann); assertEquals(1, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(1, registry.listLocalAnnouncements().size()); assertEquals(1, registry.listLocalIncomingAnnouncements().size()); assertTrue(registry.hasActiveAnnouncement(slingId)); assertFalse(registry.hasActiveAnnouncement(UUID.randomUUID().toString())); registry.unregisterAnnouncement(slingId); assertEquals(0, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(0, registry.listLocalAnnouncements().size()); assertEquals(0, registry.listLocalIncomingAnnouncements().size()); assertFalse(registry.hasActiveAnnouncement(slingId)); assertFalse(registry.hasActiveAnnouncement(UUID.randomUUID().toString())); assertEquals(1, ann.listInstances().size()); registry.addAllExcept(ann, localCluster, new AnnouncementFilter() { public boolean accept(String receivingSlingId, Announcement announcement) { assertNotNull(receivingSlingId); assertNotNull(announcement); return true; } }); assertEquals(1, ann.listInstances().size()); registry.registerAnnouncement(createAnnouncement(createCluster(3), 1, false)); assertEquals(1, registry.listAnnouncementsInSameCluster(localCluster).size()); assertEquals(3, registry.listInstances(localCluster).size()); registry.addAllExcept(ann, localCluster, new AnnouncementFilter() { public boolean accept(String receivingSlingId, Announcement announcement) { assertNotNull(receivingSlingId); assertNotNull(announcement); return true; } }); assertEquals(4, ann.listInstances().size()); registry.registerAnnouncement(ann); assertEquals(2, registry.listAnnouncementsInSameCluster(localCluster).size()); } private ClusterView createCluster(int numInstances) { DefaultClusterView localCluster = new DefaultClusterView(UUID.randomUUID().toString()); for (int i = 0; i < numInstances; i++) { DefaultInstanceDescription instance = TopologyHelper.createInstanceDescription(UUID.randomUUID().toString(), (i==0 ? true : false), localCluster); } return localCluster; } private ClusterView createCluster(String... instanceIds) { DefaultClusterView localCluster = new DefaultClusterView(UUID.randomUUID().toString()); for (int i = 0; i < instanceIds.length; i++) { DefaultInstanceDescription instance = TopologyHelper.createInstanceDescription(instanceIds[i], (i==0 ? true : false), localCluster); } return localCluster; } private Announcement createAnnouncement(ClusterView remoteCluster, int ownerIndex, boolean inherited) { List<InstanceDescription> instances = remoteCluster.getInstances(); Announcement ann = new Announcement(instances.get(ownerIndex).getSlingId()); ann.setInherited(inherited); ann.setLocalCluster(remoteCluster); return ann; } @Test public void testExpiry() throws InterruptedException, NoSuchFieldException { ClusterView cluster1 = createCluster(4); ClusterView cluster2 = createCluster(3); ClusterView cluster3 = createCluster(5); ClusterView myCluster = createCluster(slingId); Announcement ann1 = createAnnouncement(cluster1, 0, true); Announcement ann2 = createAnnouncement(cluster2, 1, true); Announcement ann3 = createAnnouncement(cluster3, 1, false); assertTrue(registry.registerAnnouncement(ann1)!=-1); assertTrue(registry.registerAnnouncement(ann2)!=-1); assertTrue(registry.registerAnnouncement(ann3)!=-1); assertTrue(registry.hasActiveAnnouncement(cluster1.getInstances().get(0).getSlingId())); assertTrue(registry.hasActiveAnnouncement(cluster2.getInstances().get(1).getSlingId())); assertTrue(registry.hasActiveAnnouncement(cluster3.getInstances().get(1).getSlingId())); assertEquals(3, registry.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(3, registry.listLocalAnnouncements().size()); assertEquals(1, registry.listLocalIncomingAnnouncements().size()); { Announcement testAnn = createAnnouncement(myCluster, 0, false); assertEquals(1, testAnn.listInstances().size()); registry.addAllExcept(testAnn, myCluster, null); assertEquals(13, testAnn.listInstances().size()); } Thread.sleep(10500); { Announcement testAnn = createAnnouncement(myCluster, 0, false); assertEquals(1, testAnn.listInstances().size()); registry.addAllExcept(testAnn, myCluster, null); assertEquals(13, testAnn.listInstances().size()); } assertTrue(registry.registerAnnouncement(ann3)!=-1); { Announcement testAnn = createAnnouncement(myCluster, 0, false); assertEquals(1, testAnn.listInstances().size()); registry.addAllExcept(testAnn, myCluster, null); assertEquals(13, testAnn.listInstances().size()); } registry.checkExpiredAnnouncements(); assertEquals(1, registry.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry.listLocalAnnouncements().size()); assertEquals(1, registry.listLocalIncomingAnnouncements().size()); assertFalse(registry.hasActiveAnnouncement(cluster1.getInstances().get(0).getSlingId())); assertFalse(registry.hasActiveAnnouncement(cluster2.getInstances().get(1).getSlingId())); assertTrue(registry.hasActiveAnnouncement(cluster3.getInstances().get(1).getSlingId())); { Announcement testAnn = createAnnouncement(myCluster, 0, false); assertEquals(1, testAnn.listInstances().size()); registry.addAllExcept(testAnn, myCluster, null); assertEquals(6, testAnn.listInstances().size()); } } @Test public void testCluster() throws Exception { doTestCluster(false); } @Category(Slow.class) @Test public void testCluster_Slow() throws Exception { doTestCluster(true); } private void doTestCluster(boolean includeFinalExpiryCheck) throws Exception { ClusterView cluster1 = createCluster(2); ClusterView cluster2 = createCluster(4); ClusterView cluster3 = createCluster(7); Announcement ann1 = createAnnouncement(cluster1, 1, true); Announcement ann2 = createAnnouncement(cluster2, 2, true); Announcement ann3 = createAnnouncement(cluster3, 3, false); final String instance1 = UUID.randomUUID().toString(); final String instance2 = UUID.randomUUID().toString(); final String instance3 = UUID.randomUUID().toString(); ClusterView myCluster = createCluster(instance1, instance2, instance3); AnnouncementRegistryImpl registry1 = AnnouncementRegistryImpl.testConstructorAndActivate( resourceResolverFactory, new DummySlingSettingsService(instance1), config); AnnouncementRegistryImpl registry2 = AnnouncementRegistryImpl.testConstructorAndActivate( resourceResolverFactory, new DummySlingSettingsService(instance2), config); AnnouncementRegistryImpl registry3 = AnnouncementRegistryImpl.testConstructorAndActivate( resourceResolverFactory, new DummySlingSettingsService(instance3), config); assertTrue(registry1.registerAnnouncement(ann1)!=-1); assertTrue(registry2.registerAnnouncement(ann2)!=-1); assertTrue(registry3.registerAnnouncement(ann3)!=-1); assertTrue(registry1.hasActiveAnnouncement(cluster1.getInstances().get(1).getSlingId())); assertTrue(registry2.hasActiveAnnouncement(cluster2.getInstances().get(2).getSlingId())); assertTrue(registry3.hasActiveAnnouncement(cluster3.getInstances().get(3).getSlingId())); assertEquals(3, registry1.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry1.listLocalAnnouncements().size()); assertEquals(0, registry1.listLocalIncomingAnnouncements().size()); assertAnnouncements(registry1, myCluster, 4, 16); assertEquals(3, registry2.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry2.listLocalAnnouncements().size()); assertEquals(0, registry2.listLocalIncomingAnnouncements().size()); assertAnnouncements(registry2, myCluster, 4, 16); assertEquals(3, registry3.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry3.listLocalAnnouncements().size()); assertEquals(1, registry3.listLocalIncomingAnnouncements().size()); assertAnnouncements(registry3, myCluster, 4, 16); myCluster = createCluster(instance1, instance2); VirtualInstanceHelper.dumpRepo(resourceResolverFactory); assertEquals(2, registry1.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry1.listLocalAnnouncements().size()); assertEquals(0, registry1.listLocalIncomingAnnouncements().size()); assertAnnouncements(registry1, myCluster, 3, 8); assertEquals(2, registry2.listAnnouncementsInSameCluster(myCluster).size()); assertEquals(1, registry2.listLocalAnnouncements().size()); assertEquals(0, registry2.listLocalIncomingAnnouncements().size()); assertAnnouncements(registry2, myCluster, 3, 8); if (includeFinalExpiryCheck) { Thread.sleep(10500); assertAnnouncements(registry1, myCluster, 3, 8); assertAnnouncements(registry2, myCluster, 3, 8); registry1.checkExpiredAnnouncements(); registry2.checkExpiredAnnouncements(); assertAnnouncements(registry1, myCluster, 1, 2); assertAnnouncements(registry2, myCluster, 1, 2); } } private void assertAnnouncements(AnnouncementRegistryImpl registry, ClusterView myCluster, int expectedNumAnnouncements, int expectedNumInstances) { Announcement ann = createAnnouncement(myCluster, 0, false); registry.addAllExcept(ann, myCluster, null); assertEquals(expectedNumInstances, ann.listInstances().size()); } }