All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl Maven / Gradle / Ivy

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;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy