blob: 40e9cdedc93b0917bcd5df0d928193f6e04e10d6 [file] [log] [blame]
/*
* 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;
}
}
}