/* * 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.brooklyn.core.location.access; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertNull; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.apache.brooklyn.util.net.Networking; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.location.access.PortForwardManager; import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.location.ssh.SshMachineLocation; import com.google.common.base.Predicate; import com.google.common.net.HostAndPort; public class PortForwardManagerTest extends BrooklynAppUnitTestSupport { private static final Logger log = LoggerFactory.getLogger(PortForwardManagerTest.class); private Map<HostAndPort, HostAndPort> portMapping; private SshMachineLocation machine1; private SshMachineLocation machine2; private PortForwardManager pfm; @Override @BeforeMethod(alwaysRun=true) public void setUp() throws Exception { super.setUp(); pfm = (PortForwardManager) mgmt.getLocationRegistry().resolve("portForwardManager(scope=global)"); machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class) .configure("address", Networking.getInetAddressWithFixedName("1.2.3.4")) .configure("port", 1234) .configure("user", "myuser")); machine2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class) .configure("address", Networking.getInetAddressWithFixedName("1.2.3.5")) .configure("port", 1234) .configure("user", "myuser")); } @Test public void testAssociateWithLocation() throws Exception { String publicIpId = "myipid"; String publicAddress = "5.6.7.8"; pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80); assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080)); assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080)); } @Test public void testAssociateWithoutLocation() throws Exception { String publicIpId = "myipid"; String publicAddress = "5.6.7.8"; pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), 80); assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080)); assertNull(pfm.lookup(machine1, 80)); } @Test public void testAcquirePortDoesNotReturnDuplicate() throws Exception { String publicIpId = "myipid"; int port1 = pfm.acquirePublicPort(publicIpId); int port2 = pfm.acquirePublicPort(publicIpId); assertNotEquals(port1, port2); } @Test public void testAcquirePortRespectsStartingPortNumber() throws Exception { BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); props.put(PortForwardManager.PORT_FORWARD_MANAGER_STARTING_PORT, 1234); LocalManagementContextForTests mgmt2 = new LocalManagementContextForTests(props); try { PortForwardManager pfm2 = (PortForwardManager) mgmt2.getLocationRegistry().resolve("portForwardManager(scope=global)"); int port = pfm2.acquirePublicPort("myipid"); assertEquals(port, 1234); } finally { Entities.destroyAll(mgmt2); } } @Test public void testForgetPortMapping() throws Exception { String publicIpId = "myipid"; String publicAddress = "5.6.7.8"; pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80); pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81); pfm.forgetPortMapping(publicIpId, 40080); assertNull(pfm.lookup(publicIpId, 80)); assertNull(pfm.lookup(machine1, 80)); assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081)); assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081)); } @Test public void testForgetPortMappingsOfMachine() throws Exception { String publicIpId = "myipid"; String publicIpId2 = "myipid2"; String publicAddress = "5.6.7.8"; pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80); pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81); pfm.associate(publicIpId2, HostAndPort.fromParts(publicAddress, 40082), machine2, 80); pfm.forgetPortMappings(machine1); assertNull(pfm.lookup(machine1, 80)); assertNull(pfm.lookup(machine1, 81)); assertNull(pfm.lookup(publicIpId, 80)); assertEquals(pfm.lookup(machine2, 80), HostAndPort.fromParts(publicAddress, 40082)); } @Test public void testAssociateLegacy() throws Exception { String publicIpId = "myipid"; String publicAddress = "5.6.7.8"; pfm.acquirePublicPortExplicit(publicIpId, 40080); pfm.recordPublicIpHostname(publicIpId, publicAddress); pfm.associate(publicIpId, 40080, machine1, 80); assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080)); assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080)); } @Test public void testAssociationListeners() throws Exception { final AtomicInteger associationCreatedCount = new AtomicInteger(0); final AtomicInteger associationDeletedCount = new AtomicInteger(0); final String publicIpId = "myipid"; final String anotherIpId = "anotherIpId"; pfm.addAssociationListener(new PortForwardManager.AssociationListener() { @Override public void onAssociationCreated(PortForwardManager.AssociationMetadata metadata) { associationCreatedCount.incrementAndGet(); } @Override public void onAssociationDeleted(PortForwardManager.AssociationMetadata metadata) { associationDeletedCount.incrementAndGet(); } }, new Predicate<PortForwardManager.AssociationMetadata>() { @Override public boolean apply(PortForwardManager.AssociationMetadata metadata) { return publicIpId.equals(metadata.getPublicIpId()); } }); pfm.associate(publicIpId, HostAndPort.fromParts(publicIpId, 40080), machine1, 80); pfm.associate(anotherIpId, HostAndPort.fromParts(anotherIpId, 40081), machine1, 80); pfm.forgetPortMapping(publicIpId, 40080); pfm.forgetPortMapping(anotherIpId, 40081); assertEquals(associationCreatedCount.get(), 1); assertEquals(associationDeletedCount.get(), 1); } }