| /* |
| * 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.internal.client.impl; |
| |
| import java.net.InetSocketAddress; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.UUID; |
| import java.util.concurrent.atomic.AtomicReference; |
| import org.apache.ignite.internal.client.GridClientCacheMode; |
| import org.apache.ignite.internal.client.GridClientNode; |
| import org.apache.ignite.internal.client.GridClientNodeMetrics; |
| import org.apache.ignite.internal.client.GridClientProtocol; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| import org.jetbrains.annotations.Nullable; |
| |
| import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CLIENT_MODE; |
| |
| /** |
| * Client node implementation. |
| */ |
| public class GridClientNodeImpl implements GridClientNode { |
| /** Node id. */ |
| private UUID nodeId; |
| |
| /** Consistent ID. */ |
| private Object consistentId; |
| |
| /** REST TCP server addresses. */ |
| private List<String> tcpAddrs = Collections.emptyList(); |
| |
| /** REST TCP server host names. */ |
| private List<String> tcpHostNames = Collections.emptyList(); |
| |
| /** Port for TCP rest binary protocol. */ |
| private int tcpPort; |
| |
| /** Node attributes. */ |
| private Map<String, Object> attrs = Collections.emptyMap(); |
| |
| /** Node metrics. */ |
| private GridClientNodeMetrics metrics; |
| |
| /** Node caches. */ |
| private Map<String, GridClientCacheMode> caches = Collections.emptyMap(); |
| |
| /** Connectable property. */ |
| private boolean connectable; |
| |
| /** Cache for REST TCP socket addresses. */ |
| private final AtomicReference<Collection<InetSocketAddress>> tcpSockAddrs = new AtomicReference<>(); |
| |
| /** Node order within grid topology */ |
| private long order; |
| |
| /** |
| * Default constructor (private). |
| */ |
| private GridClientNodeImpl() { |
| // No-op. |
| } |
| |
| /** |
| * Creates and returns a builder for a new instance |
| * of this class. |
| * |
| * @return Builder for new instance. |
| */ |
| public static Builder builder() { |
| return new Builder(new GridClientNodeImpl()); |
| } |
| |
| /** |
| * Creates and returns a builder for a new instance |
| * of this class, copying data from an input instance. |
| * |
| * @param from Instance to copy data from. |
| * @param skipAttrs Whether to skip attributes. |
| * @param skipMetrics Whether to skip metrics. |
| * @return Builder for new instance. |
| */ |
| public static Builder builder(GridClientNode from, boolean skipAttrs, boolean skipMetrics) { |
| Builder b = new Builder(new GridClientNodeImpl()) |
| .nodeId(from.nodeId()) |
| .consistentId(from.consistentId()) |
| .tcpAddresses(from.tcpAddresses()) |
| .tcpPort(from.tcpPort()) |
| .caches(from.caches()) |
| .connectable(from.connectable()) |
| .order(from.order()); |
| |
| if (!skipAttrs) |
| b.attributes(from.attributes()); |
| |
| if (!skipMetrics) |
| b.metrics(from.metrics()); |
| |
| return b; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public UUID nodeId() { |
| return nodeId; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Object consistentId() { |
| return consistentId; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public List<String> tcpAddresses() { |
| return tcpAddrs; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public List<String> tcpHostNames() { |
| return tcpHostNames; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int tcpPort() { |
| return tcpPort; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Map<String, Object> attributes() { |
| return Collections.unmodifiableMap(attrs); |
| } |
| |
| /** {@inheritDoc} */ |
| @Nullable @Override public <T> T attribute(String name) { |
| return (T)attrs.get(name); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public GridClientNodeMetrics metrics() { |
| return metrics; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Map<String, GridClientCacheMode> caches() { |
| return caches; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public Collection<InetSocketAddress> availableAddresses(GridClientProtocol proto, |
| boolean filterResolved) { |
| Collection<String> addrs; |
| Collection<String> hostNames; |
| AtomicReference<Collection<InetSocketAddress>> addrsCache; |
| final int port; |
| |
| if (proto == GridClientProtocol.TCP) { |
| addrsCache = tcpSockAddrs; |
| addrs = tcpAddrs; |
| hostNames = tcpHostNames; |
| port = tcpPort; |
| } |
| else |
| throw new AssertionError("Unknown protocol: " + proto); |
| |
| Collection<InetSocketAddress> addrs0 = addrsCache.get(); |
| |
| if (addrs0 != null) |
| return filterIfNecessary(addrs0, filterResolved); |
| |
| addrs0 = U.toSocketAddresses(addrs, hostNames, port); |
| |
| if (!addrsCache.compareAndSet(null, addrs0)) |
| return filterIfNecessary(addrsCache.get(), filterResolved); |
| |
| return filterIfNecessary(addrs0, filterResolved); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public long order() { |
| return order; |
| } |
| |
| /** |
| * Filters sockets with resolved addresses. |
| * |
| * @param addrs Addresses to filter. |
| * @param filter Flag indicating whether filter should be applied or not. |
| * @return Collection copy without unresolved addresses if flag is set and collection itself otherwise. |
| */ |
| private Collection<InetSocketAddress> filterIfNecessary(Collection<InetSocketAddress> addrs, boolean filter) { |
| if (!filter) |
| return addrs; |
| |
| List<InetSocketAddress> res = new ArrayList<>(addrs.size()); |
| |
| for (InetSocketAddress addr : addrs) |
| if (!addr.isUnresolved()) |
| res.add(addr); |
| |
| return res; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean connectable() { |
| return connectable; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean equals(Object o) { |
| if (this == o) return true; |
| |
| if (!(o instanceof GridClientNodeImpl)) return false; |
| |
| GridClientNodeImpl that = (GridClientNodeImpl)o; |
| |
| return nodeId.equals(that.nodeId); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public boolean isClient() { |
| return Objects.equals(attribute(ATTR_CLIENT_MODE), true); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int hashCode() { |
| return nodeId.hashCode(); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return "GridClientNodeImpl [nodeId=" + nodeId + |
| ", consistentId=" + consistentId + |
| ", tcpAddrs=" + tcpAddrs + |
| ", tcpHostNames=" + tcpHostNames + |
| ", binaryPort=" + tcpPort + |
| ']'; |
| } |
| |
| /** |
| * Builder for instances of this class. |
| */ |
| @SuppressWarnings("PublicInnerClass") |
| public static final class Builder { |
| /** */ |
| private GridClientNodeImpl impl; |
| |
| /** */ |
| private boolean built; |
| |
| /** |
| * @param impl Implementation reference to build. |
| */ |
| private Builder(GridClientNodeImpl impl) { |
| this.impl = impl; |
| } |
| |
| /** |
| * Finishes instance construction and returns a |
| * newly-built instance. |
| * |
| * @return A newly-built instance. |
| */ |
| public GridClientNodeImpl build() { |
| if (built) |
| throw new AssertionError("Instance already built."); |
| |
| built = true; |
| |
| return impl; |
| } |
| |
| /** |
| * Sets node ID. |
| * |
| * @param nodeId Node ID. |
| * @return This for chaining. |
| */ |
| public Builder nodeId(UUID nodeId) { |
| impl.nodeId = nodeId; |
| |
| return this; |
| } |
| |
| /** |
| * Sets node consistent ID. |
| * |
| * @param consistentId New consistent ID. |
| * @return This for chaining. |
| */ |
| public Builder consistentId(Object consistentId) { |
| impl.consistentId = consistentId; |
| |
| return this; |
| } |
| |
| /** |
| * Sets list of REST TCP server addresses. |
| * |
| * @param tcpAddrs List of address strings. |
| * @return This for chaining. |
| */ |
| public Builder tcpAddresses(Collection<String> tcpAddrs) { |
| impl.tcpAddrs = U.sealList(tcpAddrs); |
| |
| return this; |
| } |
| |
| /** |
| * Sets list of REST TCP server host names. |
| * |
| * @param tcpHostNames List of host names. |
| * @return This for chaining. |
| */ |
| public Builder tcpHostNames(Collection<String> tcpHostNames) { |
| impl.tcpHostNames = U.sealList(tcpHostNames); |
| |
| return this; |
| } |
| |
| /** |
| * Sets remote TCP port value. |
| * |
| * @param tcpPort Sets remote port value. |
| * @return This for chaining. |
| */ |
| public Builder tcpPort(int tcpPort) { |
| impl.tcpPort = tcpPort; |
| |
| return this; |
| } |
| |
| /** |
| * Sets node attributes. |
| * |
| * @param attrs Node attributes. |
| * @return This for chaining. |
| */ |
| public Builder attributes(Map<String, Object> attrs) { |
| impl.attrs = U.sealMap(attrs); |
| |
| return this; |
| } |
| |
| /** |
| * Sets node metrics. |
| * |
| * @param metrics Metrics. |
| * @return This for chaining. |
| */ |
| public Builder metrics(GridClientNodeMetrics metrics) { |
| impl.metrics = metrics; |
| |
| return this; |
| } |
| |
| /** |
| * Sets caches available on remote node. |
| * |
| * @param caches Cache map. |
| * @return This for chaining. |
| */ |
| public Builder caches(Map<String, GridClientCacheMode> caches) { |
| impl.caches = U.sealMap(caches); |
| |
| return this; |
| } |
| |
| /** |
| * Sets connectable property. |
| * |
| * @param connectable Connectable value. |
| * @return This for chaining. |
| */ |
| public Builder connectable(boolean connectable) { |
| impl.connectable = connectable; |
| |
| return this; |
| } |
| |
| /** |
| * Set node order within grid topology |
| * |
| * @param order Node order within grid topology |
| */ |
| public Builder order(long order) { |
| impl.order = order; |
| |
| return this; |
| } |
| } |
| } |