com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.cache.client.internal;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.gemstone.gemfire.CancelCriterion;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.client.PoolManager;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.distributed.internal.ServerLocation;
import com.gemstone.gemfire.internal.DummyStatisticsFactory;
import com.gemstone.gemfire.internal.cache.GatewayStats;
import com.gemstone.gemfire.internal.cache.PoolStats;
import com.gemstone.gemfire.internal.cache.tier.InternalBridgeMembership;
/**
* @author dsmith
*
*/
public class EndpointManagerImpl implements EndpointManager {
private volatile Map endpointMap = Collections.emptyMap();
private final Map/**/ statMap = new HashMap();
private final DistributedSystem ds;
private final String poolName;
private final EndpointListenerBroadcaster listener = new EndpointListenerBroadcaster();
protected final CancelCriterion cancelCriterion;
private final PoolStats poolStats;
private GatewayStats gatewayStats;
public EndpointManagerImpl(String poolName, DistributedSystem ds,CancelCriterion cancelCriterion, PoolStats poolStats) {
this.ds = ds;
this.poolName = poolName;
this.cancelCriterion = cancelCriterion;
this.poolStats = poolStats;
listener.addListener(new EndpointListenerForBridgeMembership());
//listener.addListener(new TransactionFunctionService
// .ListenerForTransactionFunctionService());
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#referenceEndpoint(com.gemstone.gemfire.distributed.internal.ServerLocation)
*/
public Endpoint referenceEndpoint(ServerLocation server, DistributedMember memberId) {
//ds.getLogWriter().warning("REFENDPOINT server:"+server+" memberId:"+memberId);
Endpoint endpoint = endpointMap.get(server);
boolean addedEndpoint = false;
if(endpoint == null || endpoint.isClosed()) {
synchronized(this) {
endpoint = endpointMap.get(server);
if(endpoint == null || endpoint.isClosed()) {
ConnectionStats stats = getStats(server);
Map endpointMapTemp = new HashMap(endpointMap);
endpoint = new Endpoint(this, ds, server, stats, memberId);
endpointMapTemp.put(server, endpoint);
endpointMap = Collections.unmodifiableMap(endpointMapTemp);
addedEndpoint = true;
poolStats.setServerCount(endpointMap.size());
}
}
}
endpoint.addReference();
if(addedEndpoint) {
//ds.getLogWriter().warning("EMANFIRE2:JOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId());
listener.endpointNowInUse(endpoint);
} else {
//ds.getLogWriter().warning("EMANFIRE33:NOJOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId());
}
return endpoint;
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#serverCrashed(com.gemstone.gemfire.cache.client.internal.Endpoint)
*/
public void serverCrashed(Endpoint endpoint) {
removeEndpoint(endpoint, true);
}
void endpointNotInUse(Endpoint endpoint) {
removeEndpoint(endpoint, false);
}
/** Used by Endpoint only, when the reference count for this endpoint reaches 0 */
private void removeEndpoint(Endpoint endpoint, boolean crashed) {
endpoint.close();
boolean removedEndpoint = false;
synchronized(this) {
Map endpointMapTemp = new HashMap(endpointMap);
endpoint = endpointMapTemp.remove(endpoint.getLocation());
if(endpoint != null) {
endpointMap = Collections.unmodifiableMap(endpointMapTemp);
removedEndpoint = true;
}
poolStats.setServerCount(endpointMap.size());
}
if(removedEndpoint) {
PoolImpl pool = (PoolImpl)PoolManager.find(this.poolName);
if (pool != null && pool.getMultiuserAuthentication()) {
int size = 0;
for (ProxyCache proxyCache : pool.getProxyCacheList()) {
try {
Long userId = proxyCache.getUserAttributes().getServerToId().remove(
endpoint.getLocation());
if (userId != null) {
++size;
}
} catch (CacheClosedException cce) {
// If this call is triggered by a Cache.close(), then this can be
// expected.
}
}
if (pool.getLoggerI18n().fineEnabled()) {
pool.getLoggerI18n().fine(
"EndpointManagerImpl.removeEndpoint() Removed server "
+ endpoint.getLocation() + " from " + size
+ " user's ProxyCache");
}
UserAttributes ua = UserAttributes.userAttributes.get();
if (ua != null) {
Long userId = ua.getServerToId().remove(endpoint.getLocation());
if (pool.getLoggerI18n().fineEnabled() && userId != null) {
pool.getLoggerI18n().fine(
"EndpointManagerImpl.removeEndpoint() Removed server "
+ endpoint.getLocation() + " from thread local variable");
}
}
} else if (pool != null && !pool.getMultiuserAuthentication()) {
endpoint.getLocation().setUserId(-1);
}
if(crashed) {
listener.endpointCrashed(endpoint);
}
else {
listener.endpointNoLongerInUse(endpoint);
}
}
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#getEndpointMap()
*/
public Map getEndpointMap() {
return endpointMap;
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#close()
*/
public synchronized void close() {
for(Iterator itr = statMap.values().iterator(); itr.hasNext(); ) {
ConnectionStats stats = itr.next();
stats.close();
}
statMap.clear();
endpointMap = Collections.emptyMap();
listener.clear();
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#addListener(com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl.EndpointListener)
*/
public void addListener(EndpointManager.EndpointListener listener) {
this.listener.addListener(listener);
}
/* (non-Javadoc)
* @see com.gemstone.gemfire.cache.client.internal.EndpointManager#removeListener(com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl.EndpointListener)
*/
public void removeListener(EndpointManager.EndpointListener listener) {
this.listener.removeListener(listener);
}
private synchronized ConnectionStats getStats(ServerLocation location) {
ConnectionStats stats = statMap.get(location);
if(stats == null) {
String statName = poolName + "-" + location.toString();
PoolImpl pool = (PoolImpl)PoolManager.find(this.poolName);
if (pool != null) {
if (pool.getGatewaySender() != null) {
stats = new ConnectionStats(new DummyStatisticsFactory(), statName,
this.poolStats, this.gatewayStats);
}
}
if (stats == null) {
stats = new ConnectionStats(ds, statName, this.poolStats,
this.gatewayStats);
}
statMap.put(location, stats);
}
return stats;
}
public synchronized Map getAllStats() {
return new HashMap(statMap);
}
public int getConnectedServerCount() {
return getEndpointMap().size();
}
public static void loadEmergencyClasses() {
//do nothing
}
protected static class EndpointListenerBroadcaster implements EndpointManager.EndpointListener {
private volatile Set/**/ endpointListeners = Collections.emptySet();
public synchronized void addListener(EndpointManager.EndpointListener listener) {
HashSet tmpListeners = new HashSet(endpointListeners);
tmpListeners.add(listener);
endpointListeners = Collections.unmodifiableSet(tmpListeners);
}
public synchronized void clear() {
endpointListeners = Collections.emptySet();
}
public void removeListener(EndpointManager.EndpointListener listener) {
HashSet tmpListeners = new HashSet(endpointListeners);
tmpListeners.remove(listener);
endpointListeners = Collections.unmodifiableSet(tmpListeners);
}
public void endpointCrashed(Endpoint endpoint) {
for(Iterator itr = endpointListeners.iterator(); itr.hasNext(); ) {
EndpointManager.EndpointListener listener = itr.next();
listener.endpointCrashed(endpoint);
}
}
public void endpointNoLongerInUse(Endpoint endpoint) {
for(Iterator itr = endpointListeners.iterator(); itr.hasNext(); ) {
EndpointManager.EndpointListener listener = itr.next();
listener.endpointNoLongerInUse(endpoint);
}
}
public void endpointNowInUse(Endpoint endpoint) {
//ds.getLogWriter().warning("HIGHUP:JOIN:"+endpoint.getLocation());
for(Iterator itr = endpointListeners.iterator(); itr.hasNext(); ) {
EndpointManager.EndpointListener listener = itr.next();
listener.endpointNowInUse(endpoint);
}
}
}
public class EndpointListenerForBridgeMembership implements EndpointManager.EndpointListener {
public void endpointCrashed(Endpoint endpoint) {
if(endpoint.getMemberId()==null || cancelCriterion.cancelInProgress()!=null) {
return;
}
//ds.getLogWriter().warning("EMANFIRE:CRASH:"+endpoint.getLocation());
InternalBridgeMembership.notifyCrashed(endpoint.getMemberId(), false);
}
public void endpointNoLongerInUse(Endpoint endpoint) {
if(endpoint.getMemberId()==null || cancelCriterion.cancelInProgress()!=null) {
return;
}
//ds.getLogWriter().warning("EMANFIRE:LEFT:"+endpoint.getLocation());
InternalBridgeMembership.notifyLeft(endpoint.getMemberId(), false);
}
public void endpointNowInUse(Endpoint endpoint) {
if(cancelCriterion.cancelInProgress()!=null) {
return;
}
//ds.getLogWriter().warning("EMANFIRE:JOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId(),new Exception());
InternalBridgeMembership.notifyJoined(endpoint.getMemberId(), false);
}
}
public String getPoolName() {
return poolName;
}
public void setGatewayStats(GatewayStats gatewayStats) {
// The gateway stats are passed to the connection stats so that it can track
// sent bytes.
this.gatewayStats = gatewayStats;
}
}