ignite-790: improvements after the review
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/5e28951e Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/5e28951e Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/5e28951e Branch: refs/heads/ignite-545 Commit: 5e28951e1f21cce6e22f29b67aea8943b154a5dc Parents: ae8d017 Author: Denis Magda <dma...@gridgain.com> Authored: Tue Apr 28 17:56:04 2015 +0300 Committer: Denis Magda <dma...@gridgain.com> Committed: Tue Apr 28 17:56:04 2015 +0300 ---------------------------------------------------------------------- modules/cloud/configs/example-aws-config.xml | 99 ----- modules/cloud/configs/example-gce-config.xml | 93 ---- .../cloud/configs/example-rackspace-config.xml | 94 ---- .../cloud/TcpDiscoveryCloudIpFinder.java | 433 +++++++++++++++++++ .../cloud/TcpDiscoveryCloudNodesIpFinder.java | 398 ----------------- .../TcpDiscoveryCloudIpFinderSelfTest.java | 124 ++++++ .../TcpDiscoveryCloudNodesIpFinderSelfTest.java | 93 ---- .../ignite/testsuites/IgniteCloudTestSuite.java | 2 +- .../discovery/tcp/TcpDiscoverySpiAdapter.java | 10 +- 9 files changed, 565 insertions(+), 781 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/configs/example-aws-config.xml ---------------------------------------------------------------------- diff --git a/modules/cloud/configs/example-aws-config.xml b/modules/cloud/configs/example-aws-config.xml deleted file mode 100644 index ba3a28e..0000000 --- a/modules/cloud/configs/example-aws-config.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - 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. ---> - -<!-- - Ignite configuration with all defaults, enabled p2p deployment, enabled events and enabled nodes auto-discovery. ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util.xsd"> - <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> - <!-- Set to true to enable distributed class loading for examples, default is false. --> - <property name="peerClassLoadingEnabled" value="true"/> - - <property name="marshaller"> - <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller"> - <!-- Set to false to allow non-serializable objects in examples, default is true. --> - <property name="requireSerializable" value="false"/> - </bean> - </property> - - <!-- Enable task execution events for examples. --> - <property name="includeEventTypes"> - <list> - <!--Task execution events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/> - - <!--Cache events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/> - </list> - </property> - - <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. --> - <property name="discoverySpi"> - <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> - <property name="ipFinder"> - - <!-- - Explicitly configure IP finder for nodes located in Google Compute Engine. - For more info on settings refer to corresponding Ignite API and to - https://jclouds.apache.org/guides/aws/. - --> - <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudNodesIpFinder"> - <property name="provider" value="aws-ec2"/> - <property name="identity" value="Ahjdns2323_TEST_ID"/> - <property name="credential" value="Jkndwqo89834Jkljdlsd_TEST_KEY"/> - <property name="discoveryPort" value="45712"/> - - <property name="regions"> - <list> - <value>us-east-1</value> - </list> - </property> - - <property name="zones"> - <list> - <value>us-east-1b</value> - <value>us-east-1e</value> - </list> - </property> - </bean> - </property> - - <!-- All nodes must be started on the same port. So localPort must be equal to - TcpDiscoveryCloudNodesIpFinder.discoveryPort --> - <property name="localPort" value="45712"/> - - <property name="socketTimeout" value="400"/> - </bean> - </property> - </bean> -</beans> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/configs/example-gce-config.xml ---------------------------------------------------------------------- diff --git a/modules/cloud/configs/example-gce-config.xml b/modules/cloud/configs/example-gce-config.xml deleted file mode 100644 index a3a912a..0000000 --- a/modules/cloud/configs/example-gce-config.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - 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. ---> - -<!-- - Ignite configuration with all defaults, enabled p2p deployment, enabled events and enabled nodes auto-discovery. ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util.xsd"> - <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> - <!-- Set to true to enable distributed class loading for examples, default is false. --> - <property name="peerClassLoadingEnabled" value="true"/> - - <property name="marshaller"> - <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller"> - <!-- Set to false to allow non-serializable objects in examples, default is true. --> - <property name="requireSerializable" value="false"/> - </bean> - </property> - - <!-- Enable task execution events for examples. --> - <property name="includeEventTypes"> - <list> - <!--Task execution events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/> - - <!--Cache events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/> - </list> - </property> - - <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. --> - <property name="discoverySpi"> - <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> - <property name="ipFinder"> - - <!-- - Explicitly configure IP finder for nodes located in Google Compute Engine. - For more info on settings refer to corresponding Ignite API and to - https://jclouds.apache.org/guides/google/. - --> - <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudNodesIpFinder"> - <property name="provider" value="google-compute-engine"/> - <property name="identity" value="209979073-te...@developer.gserviceaccount.com"/> - <property name="credentialPath" value="\var\credential\key.pem"/> - <property name="discoveryPort" value="45712"/> - <property name="zones"> - <list> - <value>us-central1-a</value> - <value>asia-east1-a</value> - <value>europe-west1-b</value> - </list> - </property> - </bean> - </property> - - <!-- All nodes must be started on the same port. So localPort must be equal to - TcpDiscoveryCloudNodesIpFinder.discoveryPort --> - <property name="localPort" value="45712"/> - - <property name="socketTimeout" value="400"/> - </bean> - </property> - </bean> -</beans> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/configs/example-rackspace-config.xml ---------------------------------------------------------------------- diff --git a/modules/cloud/configs/example-rackspace-config.xml b/modules/cloud/configs/example-rackspace-config.xml deleted file mode 100644 index 227bcbc..0000000 --- a/modules/cloud/configs/example-rackspace-config.xml +++ /dev/null @@ -1,94 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - 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. ---> - -<!-- - Ignite configuration with all defaults, enabled p2p deployment, enabled events and enabled nodes auto-discovery. ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util.xsd"> - <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> - <!-- Set to true to enable distributed class loading for examples, default is false. --> - <property name="peerClassLoadingEnabled" value="true"/> - - <property name="marshaller"> - <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller"> - <!-- Set to false to allow non-serializable objects in examples, default is true. --> - <property name="requireSerializable" value="false"/> - </bean> - </property> - - <!-- Enable task execution events for examples. --> - <property name="includeEventTypes"> - <list> - <!--Task execution events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/> - - <!--Cache events--> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/> - <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/> - </list> - </property> - - <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. --> - <property name="discoverySpi"> - <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> - <property name="ipFinder"> - - <!-- - Explicitly configure IP finder for nodes located in Google Compute Engine. - For more info on settings refer to corresponding Ignite API and to - https://jclouds.apache.org/guides/rackspace/. - --> - <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudNodesIpFinder"> - <property name="provider" value="rackspace-cloudservers-us"/> - <property name="identity" value="username"/> - <property name="credential" value="7878a5a5b1aba2c4626TEST_KEY"/> - <property name="discoveryPort" value="45712"/> - <property name="regions"> - <list> - <value>IAD</value> - <value>HKG</value> - </list> - </property> - </bean> - </property> - - <!-- - All nodes must be started on the same port. So localPort must be equal to - TcpDiscoveryCloudNodesIpFinder.discoveryPort - --> - <property name="localPort" value="45712"/> - - <property name="socketTimeout" value="400"/> - </bean> - </property> - </bean> -</beans> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinder.java ---------------------------------------------------------------------- diff --git a/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinder.java b/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinder.java new file mode 100644 index 0000000..2637742 --- /dev/null +++ b/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinder.java @@ -0,0 +1,433 @@ +/* + * 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.ignite.spi.discovery.tcp.ipfinder.cloud; + +import com.google.common.base.*; +import com.google.common.io.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.util.tostring.*; +import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.spi.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.jclouds.*; +import org.jclouds.compute.*; +import org.jclouds.compute.domain.*; +import org.jclouds.domain.*; +import org.jclouds.location.reference.*; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +/** + * IP finder for automatic lookup of nodes running in a cloud. + * <p> + * Implementation is based on Apache jclouds multi-cloud toolkit. + * For information about jclouds visit <a href="https://jclouds.apache.org/">jclouds.apache.org</a>. + * <h1 class="header">Configuration</h1> + * <h2 class="header">Mandatory</h2> + * <ul> + * <li>Cloud provider (see {@link #setProvider(String)})</li> + * <li>Identity (see {@link #setIdentity(String)})</li> + * </ul> + * <h2 class="header">Optional</h2> + * <ul> + * <li>Credential (see {@link #setCredential(String)})</li> + * <li>Credential path (see {@link #setCredentialPath(String)}</li> + * <li>Regions (see {@link #setRegions(Collection)})</li> + * <li>Zones (see {@link #setZones(Collection)}</li> + * </ul> + * </p> + * <p> + * The finder forms nodes addresses, that possibly running Ignite, by getting private and public IPs of all + * VMs in a cloud and adding a port number to them. + * The port is either the one that is set with {@link TcpDiscoverySpi#setLocalPort(int)} or + * {@link TcpDiscoverySpi#DFLT_PORT}. + * Make sure that all VMs start Ignite instances on the same port, otherwise they will not be able to discover each + * other using this IP finder. + * </p> + * <p> + * Both {@link #registerAddresses(Collection)} and {@link #unregisterAddresses(Collection)} has no effect. + * </p> + * <p> + * Note, this finder is only workable when it used directly by cloud VM. + * Choose another implementation of {@link org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder} for local + * or home network tests. + * </p> + * <h2 class="header">Java Example</h2> + * <pre name="code" class="java"> + * String accountId = "your_account_id"; + * String accountKey = "your_account_key"; + * + * TcpDiscoveryCloudIpFinder ipFinder = new TcpDiscoveryCloudIpFinder(); + * + * ipFinder.setProvider("aws-ec2"); + * ipFinder.setIdentity(accountId); + * ipFinder.setCredential(accountKey); + * ipFinder.setRegions(Collections.<String>emptyList().add("us-east-1")); + * ipFinder.setZones(Arrays.asList("us-east-1b", "us-east-1e")); + * </pre> + * <h2 class="header">Spring Example</h2> + * TcpDiscoveryCloudIpFinder can be configured from Spring XML configuration file: + * <pre name="code" class="xml"> + * <bean id="grid.custom.cfg" class="org.apache.ignite.configuration.IgniteConfiguration" singleton="true"> + * ... + * <property name="discoverySpi"> + * <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + * <property name="ipFinder"> + * <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder"/> + * <property name="provider" value="google-compute-engine"/> + * <property name="identity" value="your_service_account_email"/> + * <property name="credentialPath" value="path_to_pem_file"/> + * <property name="zones"> + * <list> + * <value>us-central1-a</value> + * <value>asia-east1-a</value> + * </list> + * </property> + * </bean> + * </property> + * + * <property name="socketTimeout" value="400"/> + * </bean> + * </property> + * ... + * </bean> + * </pre> + * <p> + * <img src="http://ignite.incubator.apache.org/images/spring-small.png"> + * <br> + * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a> + */ +public class TcpDiscoveryCloudIpFinder extends TcpDiscoveryIpFinderAdapter { + /* JCloud default connection timeout. */ + private final static String JCLOUD_CONNECTION_TIMEOUT = "10000"; //10 secs + + /* Cloud provider. */ + private String provider; + + /* Cloud specific identity (user name, email address, etc.). */ + private String identity; + + /* Cloud specific credential (password, access key, etc.). */ + @GridToStringExclude + private String credential; + + /* Path to a cloud specific credential. */ + @GridToStringExclude + private String credentialPath; + + /* Regions where VMs are located. */ + private TreeSet<String> regions; + + /* Zones where VMs are located. */ + private TreeSet<String> zones; + + /* Nodes filter by regions and zones. */ + private Predicate<ComputeMetadata> nodesFilter; + + /** Init guard. */ + @GridToStringExclude + private final AtomicBoolean initGuard = new AtomicBoolean(); + + /** Init latch. */ + @GridToStringExclude + private final CountDownLatch initLatch = new CountDownLatch(1); + + /* JCloud compute service. */ + private ComputeService computeService; + + /** + * Constructor. + */ + public TcpDiscoveryCloudIpFinder() { + setShared(true); + } + + /** {@inheritDoc} */ + @Override public Collection<InetSocketAddress> getRegisteredAddresses() throws IgniteSpiException { + initComputeService(); + + Collection<InetSocketAddress> addresses = new LinkedList<>(); + + try { + Set<NodeMetadata> nodes; + + if (nodesFilter != null) + nodes = (Set<NodeMetadata>)computeService.listNodesDetailsMatching(nodesFilter); + else { + nodes = new HashSet<>(); + + for (ComputeMetadata metadata : computeService.listNodes()) + nodes.add(computeService.getNodeMetadata(metadata.getId())); + } + + for (NodeMetadata metadata : nodes) { + if (metadata.getStatus() != NodeMetadata.Status.RUNNING) + continue; + + for (String addr : metadata.getPrivateAddresses()) + addresses.add(new InetSocketAddress(addr, 0)); + + for (String addr : metadata.getPublicAddresses()) + addresses.add(new InetSocketAddress(addr, 0)); + } + } + catch (Exception e) { + throw new IgniteSpiException("Failed to get registered addresses for the provider: " + provider, e); + } + + return addresses; + } + + /** {@inheritDoc} */ + @Override public void registerAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { + // No-op + } + + /** {@inheritDoc} */ + @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { + // No-op + } + + /** + * Sets the cloud provider to use. + * + * <a href="https://jclouds.apache.org/reference/providers/#compute">Apache jclouds providers list</a> from + * ComputeService section contains names of all supported providers. + * + * @param provider Provider name. + */ + @IgniteSpiConfiguration(optional = false) + public void setProvider(String provider) { + this.provider = provider; + } + + /** + * Sets the identity that is used as a user name during a connection to the cloud. + * Depending on a cloud platform it can be an email address, user name, etc. + * + * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on + * what is used as an identity for a particular cloud platform. + * + * @param identity Identity to use during authentication on the cloud. + */ + @IgniteSpiConfiguration(optional = false) + public void setIdentity(String identity) { + this.identity = identity; + } + + /** + * Sets credential that is used during authentication on the cloud. + * Depending on a cloud platform it can be a password or access key. + * + * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on + * what is used as an credential for a particular cloud platform. + * + * @param credential Credential to use during authentication on the cloud. + */ + @IgniteSpiConfiguration(optional = true) + public void setCredential(String credential) { + this.credential = credential; + } + + /** + * Sets the path to a credential that is used during authentication on the cloud. + * + * This method should be used when an access key or private key is stored in a plain or PEM file without + * a passphrase. + * Content of the file, referred by @{code credentialPath}, is fully read and used as a access key or private key + * during authentication. + * + * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on + * what is used as an credential for a particular cloud platform. + * + * @param credentialPath Path to the credential to use during authentication on the cloud. + */ + @IgniteSpiConfiguration(optional = true) + public void setCredentialPath(String credentialPath) { + this.credentialPath = credentialPath; + } + + /** + * Sets list of zones where VMs are located. + * + * If the zones are not set then every zone from regions, set by {@link #setRegions(Collection)}}, will be + * taken into account. + * + * Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such + * providers a call to this method is redundant. + * + * @param zones Zones where VMs are located or null if to take every zone into account. + */ + @IgniteSpiConfiguration(optional = true) + public void setZones(Collection<String> zones) { + if (F.isEmpty(zones)) + return; + + this.zones = new TreeSet<>(zones); + } + + /** + * Sets list of regions where VMs are located. + * + * If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead + * to significant performance degradation. + * + * Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such + * providers a call to this method is redundant. + * + * @param regions Regions where VMs are located or null if to check every region a provider has. + */ + @IgniteSpiConfiguration(optional = true) + public void setRegions(Collection<String> regions) { + if (F.isEmpty(regions)) + return; + + this.regions = new TreeSet<>(regions); + } + + /** + * Initializes Apache jclouds compute service. + */ + private void initComputeService() { + if (initGuard.compareAndSet(false, true)) + try { + if (provider == null) + throw new IgniteSpiException("Cloud provider is not set."); + + if (identity == null) + throw new IgniteSpiException("Cloud identity is not set."); + + if (credential != null && credentialPath != null) + throw new IgniteSpiException("Both credential and credentialPath are set. Use only one method."); + + if (credentialPath != null) + credential = getPrivateKeyFromFile(); + + try { + ContextBuilder ctxBuilder = ContextBuilder.newBuilder(provider); + + ctxBuilder.credentials(identity, credential); + + Properties properties = new Properties(); + properties.setProperty(Constants.PROPERTY_SO_TIMEOUT, JCLOUD_CONNECTION_TIMEOUT); + properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, JCLOUD_CONNECTION_TIMEOUT); + + if (!F.isEmpty(regions)) + properties.setProperty(LocationConstants.PROPERTY_REGIONS, keysSetToStr(regions)); + + if (!F.isEmpty(zones)) + properties.setProperty(LocationConstants.PROPERTY_ZONES, keysSetToStr(zones)); + + ctxBuilder.overrides(properties); + + computeService = ctxBuilder.buildView(ComputeServiceContext.class).getComputeService(); + + if (!F.isEmpty(zones) || !F.isEmpty(regions)) { + nodesFilter = new Predicate<ComputeMetadata>() { + @Override public boolean apply(ComputeMetadata computeMetadata) { + String region = null; + String zone = null; + + Location location = computeMetadata.getLocation(); + + while (location != null) { + switch (location.getScope()) { + case ZONE: + zone = location.getId(); + break; + + case REGION: + region = location.getId(); + break; + } + + location = location.getParent(); + } + + if (regions != null && region != null && !regions.contains(region)) + return false; + + if (zones != null && zone != null && !zones.contains(zone)) + return false; + + return true; + } + }; + } + } + catch (Exception e) { + throw new IgniteSpiException("Failed to connect to the provider: " + provider, e); + } + } + finally { + initLatch.countDown(); + } + else + { + try { + U.await(initLatch); + } + catch (IgniteInterruptedCheckedException e) { + throw new IgniteSpiException("Thread has been interrupted.", e); + } + + if (computeService == null) + throw new IgniteSpiException("Ip finder has not been initialized properly."); + } + } + + /** + * Retrieves a private key from the secrets file. + * + * @return Private key + */ + private String getPrivateKeyFromFile() throws IgniteSpiException { + try { + return Files.toString(new File(credentialPath), Charsets.UTF_8); + } + catch (IOException e) { + throw new IgniteSpiException("Failed to retrieve the private key from the file: " + credentialPath, e); + } + } + + /** + * Converts set keys to string. + * + * @param set Set. + * @return String where keys delimited by ','. + */ + private String keysSetToStr(Set<String> set) { + Iterator<String> iter = set.iterator(); + StringBuilder builder = new StringBuilder(); + + while (iter.hasNext()) { + builder.append(iter.next()); + + if (iter.hasNext()) + builder.append(','); + } + + return builder.toString(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinder.java ---------------------------------------------------------------------- diff --git a/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinder.java b/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinder.java deleted file mode 100644 index d5bb699..0000000 --- a/modules/cloud/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinder.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * 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.ignite.spi.discovery.tcp.ipfinder.cloud; - -import com.google.common.base.*; -import com.google.common.io.*; -import org.apache.ignite.internal.*; -import org.apache.ignite.internal.util.tostring.*; -import org.apache.ignite.internal.util.typedef.*; -import org.apache.ignite.internal.util.typedef.internal.*; -import org.apache.ignite.spi.*; -import org.apache.ignite.spi.discovery.tcp.*; -import org.apache.ignite.spi.discovery.tcp.ipfinder.*; -import org.jclouds.*; -import org.jclouds.compute.*; -import org.jclouds.compute.domain.*; -import org.jclouds.domain.*; -import org.jclouds.location.reference.*; - -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - -/** - * IP finder for automatic lookup of nodes running in a cloud. - * <p> - * Implementation is based on Apache jclouds multi-cloud toolkit. - * For information about jclouds visit <a href="https://jclouds.apache.org/">jclouds.apache.org</a>. - * <h1 class="header">Configuration</h1> - * <h2 class="header">Mandatory</h2> - * <ul> - * <li>Cloud provider (see {@link #setProvider(String)})</li> - * <li>Identity (see {@link #setIdentity(String)})</li> - * </ul> - * <h2 class="header">Optional</h2> - * <ul> - * <li>Credential (see {@link #setCredential(String)})</li> - * <li>Discovery port (see {@link #setDiscoveryPort(Integer)})</li> - * </ul> - * </p> - * <p> - * The finder forms nodes addresses, that possibly running Ignite, by getting private and public IPs of all - * VMs in a cloud and adding {@link #discoveryPort} to them. - * Both {@link #registerAddresses(Collection)} and {@link #unregisterAddresses(Collection)} has no effect. - * </p> - * <p> - * Note, this finder is only workable when it used directly by a cloud VM. - * Choose another implementation of {@link org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder} for local - * or home network tests. - * </p> - */ -public class TcpDiscoveryCloudNodesIpFinder extends TcpDiscoveryIpFinderAdapter { - /* JCloud default connection timeout. */ - private final static String JCLOUD_CONNECTION_TIMEOUT = "10000"; //10 secs - - /* Cloud provider. */ - private String provider; - - /* Cloud specific identity (user name, email address, etc.). */ - private String identity; - - /* Cloud specific credential (password, access key, etc.). */ - @GridToStringExclude - private String credential; - - /* Path to a cloud specific credential. */ - @GridToStringExclude - private String credentialPath; - - /* Regions where VMs are located. */ - private TreeSet<String> regions; - - /* Zones where VMs are located. */ - private TreeSet<String> zones; - - /* Nodes filter by regions and zones. */ - private Predicate<ComputeMetadata> nodesFilter; - - /* Port to use to connect to nodes across a cluster. */ - private Integer discoveryPort; - - /** Init guard. */ - @GridToStringExclude - private final AtomicBoolean initGuard = new AtomicBoolean(); - - /** Init latch. */ - @GridToStringExclude - private final CountDownLatch initLatch = new CountDownLatch(1); - - /* JCloud compute service. */ - private ComputeService computeService; - - /** - * Constructor. - */ - public TcpDiscoveryCloudNodesIpFinder() { - setShared(true); - } - - /** {@inheritDoc} */ - @Override public Collection<InetSocketAddress> getRegisteredAddresses() throws IgniteSpiException { - initComputeService(); - - Collection<InetSocketAddress> addresses = new LinkedList<>(); - - try { - Set<NodeMetadata> nodes; - - if (nodesFilter != null) - nodes = (Set<NodeMetadata>)computeService.listNodesDetailsMatching(nodesFilter); - else { - nodes = new HashSet<>(); - - for (ComputeMetadata metadata : computeService.listNodes()) - nodes.add(computeService.getNodeMetadata(metadata.getId())); - } - - for (NodeMetadata metadata : nodes) { - for (String addr : metadata.getPrivateAddresses()) - addresses.add(new InetSocketAddress(addr, discoveryPort)); - - for (String addr : metadata.getPublicAddresses()) - addresses.add(new InetSocketAddress(addr, discoveryPort)); - } - } - catch (Exception e) { - throw new IgniteSpiException("Failed to get registered addresses for the provider: " + provider, e); - } - - return addresses; - } - - /** {@inheritDoc} */ - @Override public void registerAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { - // No-op - } - - /** {@inheritDoc} */ - @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { - // No-op - } - - /** - * Sets the cloud provider to use. - * - * <a href="https://jclouds.apache.org/reference/providers/#compute">Apache jclouds providers list</a> from - * ComputeService section contains names of all supported providers. - * - * @param provider Provider name. - */ - @IgniteSpiConfiguration(optional = false) - public void setProvider(String provider) { - this.provider = provider; - } - - /** - * Sets the identity that is used as a user name during a connection to the cloud. - * Depending on a cloud platform it can be an email address, user name, etc. - * - * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on - * what is used as an identity for a particular cloud platform. - * - * @param identity Identity to use during authentication on the cloud. - */ - @IgniteSpiConfiguration(optional = false) - public void setIdentity(String identity) { - this.identity = identity; - } - - /** - * Sets credential that is used during authentication on the cloud. - * Depending on a cloud platform it can be a password or access key. - * - * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on - * what is used as an credential for a particular cloud platform. - * - * @param credential Credential to use during authentication on the cloud. - */ - @IgniteSpiConfiguration(optional = true) - public void setCredential(String credential) { - this.credential = credential; - } - - /** - * Sets the path to a credential that is used during authentication on the cloud. - * - * This method should be used when an access key or private key is stored in a plain or PEM file without - * a passphrase. - * Content of the file, referred by @{code credentialPath}, is fully read and used as a access key or private key - * during authentication. - * - * Refer to <a href="http://jclouds.apache.org/guides/">Apache jclouds guide</a> to get concrete information on - * what is used as an credential for a particular cloud platform. - * - * @param credentialPath Path to the credential to use during authentication on the cloud. - */ - @IgniteSpiConfiguration(optional = true) - public void setCredentialPath(String credentialPath) { - this.credentialPath = credentialPath; - } - - /** - * Sets the port that is used to discover other nodes running Apache Ignite in the cloud. - * If doesn't set, a default port number is used. - * - * Note that all cloud nodes must accept connection on the same port number. - * - * @param discoveryPort Port number to use for discovering of other nodes. - */ - @IgniteSpiConfiguration(optional = true) - public void setDiscoveryPort(Integer discoveryPort) { - this.discoveryPort = discoveryPort; - } - - /** - * Sets list of zones where VMs are located. - * - * If the zones are not set then every zone from regions, set by {@link #setRegions(Collection)}}, will be - * taken into account. - * - * Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such - * providers a call to this method is redundant. - * - * @param zones Zones where VMs are located or null if to take every zone into account. - */ - @IgniteSpiConfiguration(optional = true) - public void setZones(Collection<String> zones) { - if (F.isEmpty(zones)) - return; - - this.zones = new TreeSet<>(zones); - } - - /** - * Sets list of regions where VMs are located. - * - * If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead - * to significant performance degradation. - * - * Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such - * providers a call to this method is redundant. - * - * @param regions Regions where VMs are located or null if to check every region a provider has. - */ - @IgniteSpiConfiguration(optional = true) - public void setRegions(Collection<String> regions) { - if (F.isEmpty(regions)) - return; - - this.regions = new TreeSet<>(regions); - } - - /** - * Initializes Apache jclouds compute service. - */ - private void initComputeService() { - if (initGuard.compareAndSet(false, true)) - try { - if (provider == null) - throw new IgniteSpiException("Cloud provider is not set."); - - if (identity == null) - throw new IgniteSpiException("Cloud identity is not set."); - - if (credential != null && credentialPath != null) - throw new IgniteSpiException("Both credential and credentialPath are set. Use only one method."); - - if (credentialPath != null) - credential = getPrivateKeyFromFile(); - - try { - ContextBuilder ctxBuilder = ContextBuilder.newBuilder(provider); - - ctxBuilder.credentials(identity, credential); - - Properties properties = new Properties(); - properties.setProperty(Constants.PROPERTY_SO_TIMEOUT, JCLOUD_CONNECTION_TIMEOUT); - properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, JCLOUD_CONNECTION_TIMEOUT); - - if (!F.isEmpty(regions)) - properties.setProperty(LocationConstants.PROPERTY_REGIONS, keysSetToStr(regions)); - - if (!F.isEmpty(zones)) - properties.setProperty(LocationConstants.PROPERTY_ZONES, keysSetToStr(zones)); - - ctxBuilder.overrides(properties); - - computeService = ctxBuilder.buildView(ComputeServiceContext.class).getComputeService(); - - if (!F.isEmpty(zones) || !F.isEmpty(regions)) { - nodesFilter = new Predicate<ComputeMetadata>() { - @Override public boolean apply(ComputeMetadata computeMetadata) { - String region = null; - String zone = null; - - Location location = computeMetadata.getLocation(); - - while (location != null) { - switch (location.getScope()) { - case ZONE: - zone = location.getId(); - break; - - case REGION: - region = location.getId(); - break; - } - - location = location.getParent(); - } - - if (regions != null && region != null && !regions.contains(region)) - return false; - - if (zones != null && zone != null && !zones.contains(zone)) - return false; - - return true; - } - }; - } - } - catch (Exception e) { - throw new IgniteSpiException("Failed to connect to the provider: " + provider, e); - } - - if (discoveryPort == null) - discoveryPort = TcpDiscoverySpi.DFLT_PORT; - - } - finally { - initLatch.countDown(); - } - else - { - try { - U.await(initLatch); - } - catch (IgniteInterruptedCheckedException e) { - throw new IgniteSpiException("Thread has been interrupted.", e); - } - - if (computeService == null) - throw new IgniteSpiException("Ip finder has not been initialized properly."); - } - } - - /** - * Retrieves a private key from the secrets file. - * - * @return Private key - */ - private String getPrivateKeyFromFile() throws IgniteSpiException { - try { - return Files.toString(new File(credentialPath), Charsets.UTF_8); - } - catch (IOException e) { - throw new IgniteSpiException("Failed to retrieve the private key from the file: " + credentialPath, e); - } - } - - /** - * Converts set keys to string. - * - * @param set Set. - * @return String where keys delimited by ','. - */ - private String keysSetToStr(Set<String> set) { - Iterator<String> iter = set.iterator(); - StringBuilder builder = new StringBuilder(); - - while (iter.hasNext()) { - builder.append(iter.next()); - - if (iter.hasNext()) - builder.append(','); - } - - return builder.toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinderSelfTest.java b/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinderSelfTest.java new file mode 100644 index 0000000..7ac1994 --- /dev/null +++ b/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudIpFinderSelfTest.java @@ -0,0 +1,124 @@ +/* + * 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.ignite.spi.discovery.tcp.ipfinder.cloud; + +import com.google.common.collect.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.testsuites.*; + +import java.net.*; +import java.util.*; + +/** + * TcpDiscoveryCloudIpFinder test. + */ +public class TcpDiscoveryCloudIpFinderSelfTest extends + TcpDiscoveryIpFinderAbstractSelfTest<TcpDiscoveryCloudIpFinder> { + /** + * Constructor. + * + * @throws Exception If any error occurs. + */ + public TcpDiscoveryCloudIpFinderSelfTest() throws Exception { + // No-op. + } + + @Override protected void beforeTest() throws Exception { + // No-op. + } + + /* {@inheritDoc} */ + @Override protected TcpDiscoveryCloudIpFinder ipFinder() throws Exception { + // No-op. + return null; + } + + /* {@inheritDoc} */ + @Override public void testIpFinder() throws Exception { + // No-op + } + + /** + * Tests AWS. + * + * @throws Exception If any error occurs. + */ + public void testAmazonWebServices() throws Exception { + testCloudProvider("aws-ec2"); + } + + /** + * Tests GCE. + * + * @throws Exception If any error occurs. + */ + public void testGoogleComputeEngine() throws Exception { + testCloudProvider("google-compute-engine"); + } + + /** + * Tests Rackspace. + * + * @throws Exception If any error occurs. + */ + public void testRackspace() throws Exception { + testCloudProvider("rackspace-cloudservers-us"); + } + + /** + * Tests a given provider. + * + * @param provider Provider name. + * @throws Exception If any error occurs. + */ + private void testCloudProvider(String provider) throws Exception { + info("Testing provider: " + provider); + + TcpDiscoveryCloudIpFinder ipFinder = new TcpDiscoveryCloudIpFinder(); + + injectLogger(ipFinder); + + ipFinder.setProvider(provider); + ipFinder.setIdentity(IgniteCloudTestSuite.getAccessKey(provider)); + ipFinder.setRegions(IgniteCloudTestSuite.getRegions(provider)); + ipFinder.setZones(IgniteCloudTestSuite.getZones(provider)); + + if (provider.equals("google-compute-engine")) + ipFinder.setCredentialPath(IgniteCloudTestSuite.getSecretKey(provider)); + else { + ipFinder.setCredential(IgniteCloudTestSuite.getSecretKey(provider)); + } + + Collection<InetSocketAddress> addresses = ipFinder.getRegisteredAddresses(); + + assert addresses.size() > 0; + + for (InetSocketAddress addr : addresses) + info("Registered instance: " + addr.getAddress().getHostAddress() + ":" + addr.getPort()); + + ipFinder.unregisterAddresses(addresses); + + assert addresses.size() == ipFinder.getRegisteredAddresses().size(); + + ipFinder.registerAddresses(ImmutableList.of( + new InetSocketAddress("192.168.0.1", TcpDiscoverySpi.DFLT_PORT))); + + assert addresses.size() == ipFinder.getRegisteredAddresses().size(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinderSelfTest.java b/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinderSelfTest.java deleted file mode 100644 index 9202ac6..0000000 --- a/modules/cloud/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/cloud/TcpDiscoveryCloudNodesIpFinderSelfTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.ignite.spi.discovery.tcp.ipfinder.cloud; - -import com.google.common.collect.*; -import org.apache.ignite.spi.discovery.tcp.*; -import org.apache.ignite.spi.discovery.tcp.ipfinder.*; -import org.apache.ignite.testsuites.*; - -import java.net.*; -import java.util.*; - -/** - * TcpDiscoveryCloudNodesIpFinder test. - */ -public class TcpDiscoveryCloudNodesIpFinderSelfTest extends - TcpDiscoveryIpFinderAbstractSelfTest<TcpDiscoveryCloudNodesIpFinder> { - /** - * Constructor. - * - * @throws Exception If any error occurs. - */ - public TcpDiscoveryCloudNodesIpFinderSelfTest() throws Exception { - // No-op. - } - - @Override protected void beforeTest() throws Exception { - // No-op. - } - - /* {@inheritDoc} */ - @Override protected TcpDiscoveryCloudNodesIpFinder ipFinder() throws Exception { - // No-op. - return null; - } - - /* {@inheritDoc} */ - @Override public void testIpFinder() throws Exception { - TcpDiscoveryCloudNodesIpFinder ipFinder; - String[] providers = {"google-compute-engine", "aws-ec2", "rackspace-cloudservers-us"}; - - for (String provider : providers) { - info("Testing provider: " + provider); - - ipFinder = new TcpDiscoveryCloudNodesIpFinder(); - injectLogger(ipFinder); - - ipFinder.setProvider(provider); - ipFinder.setIdentity(IgniteCloudTestSuite.getAccessKey(provider)); - ipFinder.setRegions(IgniteCloudTestSuite.getRegions(provider)); - ipFinder.setZones(IgniteCloudTestSuite.getZones(provider)); - - if (provider.equals("google-compute-engine")) - ipFinder.setCredentialPath(IgniteCloudTestSuite.getSecretKey(provider)); - else { - ipFinder.setCredential(IgniteCloudTestSuite.getSecretKey(provider)); - } - - ipFinder.setDiscoveryPort(TcpDiscoverySpi.DFLT_PORT); - - Collection<InetSocketAddress> addresses = ipFinder.getRegisteredAddresses(); - - assert addresses.size() > 0; - - for (InetSocketAddress addr: addresses) - info("Registered instance: " + addr.getAddress().getHostAddress() + ":" + addr.getPort()); - - ipFinder.unregisterAddresses(addresses); - - assert addresses.size() == ipFinder.getRegisteredAddresses().size(); - - ipFinder.registerAddresses(ImmutableList.of( - new InetSocketAddress("192.168.0.1", TcpDiscoverySpi.DFLT_PORT))); - - assert addresses.size() == ipFinder.getRegisteredAddresses().size(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/cloud/src/test/java/org/apache/ignite/testsuites/IgniteCloudTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/cloud/src/test/java/org/apache/ignite/testsuites/IgniteCloudTestSuite.java b/modules/cloud/src/test/java/org/apache/ignite/testsuites/IgniteCloudTestSuite.java index b542c27..28d4436 100644 --- a/modules/cloud/src/test/java/org/apache/ignite/testsuites/IgniteCloudTestSuite.java +++ b/modules/cloud/src/test/java/org/apache/ignite/testsuites/IgniteCloudTestSuite.java @@ -33,7 +33,7 @@ public class IgniteCloudTestSuite extends TestSuite { TestSuite suite = new TestSuite("Cloud Integration Test Suite"); // Cloud Nodes IP finder. - suite.addTest(new TestSuite(TcpDiscoveryCloudNodesIpFinderSelfTest.class)); + suite.addTest(new TestSuite(TcpDiscoveryCloudIpFinderSelfTest.class)); return suite; } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5e28951e/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiAdapter.java index 98e048d..26f6869 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpiAdapter.java @@ -680,9 +680,13 @@ abstract class TcpDiscoverySpiAdapter extends IgniteSpiAdapter implements Discov Collection<InetSocketAddress> res = new ArrayList<>(); for (InetSocketAddress addr : ipFinder.getRegisteredAddresses()) { - if (addr.getPort() == 0) - addr = addr.isUnresolved() ? new InetSocketAddress(addr.getHostName(), DFLT_PORT) : - new InetSocketAddress(addr.getAddress(), DFLT_PORT); + if (addr.getPort() == 0) { + // TcpDiscoveryNode.discoveryPort() returns an correct port for a server node and 0 for client node. + int port = locNode.discoveryPort() != 0 ? locNode.discoveryPort() : DFLT_PORT; + + addr = addr.isUnresolved() ? new InetSocketAddress(addr.getHostName(), port) : + new InetSocketAddress(addr.getAddress(), port); + } res.add(addr); }