Package org.teiid.cache.jboss

Source Code of org.teiid.cache.jboss.ClusteredTupleBatchCacheLoader$ResponseValidityFilter

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.cache.jboss;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.cache.CacheStatus;
import org.jboss.cache.Fqn;
import org.jboss.cache.Modification;
import org.jboss.cache.RegionManager;
import org.jboss.cache.ReplicationException;
import org.jboss.cache.commands.CommandsFactory;
import org.jboss.cache.commands.DataCommand;
import org.jboss.cache.commands.read.ExistsCommand;
import org.jboss.cache.commands.read.GetDataMapCommand;
import org.jboss.cache.commands.remote.ClusteredGetCommand;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.loader.AbstractCacheLoader;
import org.jboss.cache.lock.StripedLock;
import org.jgroups.Address;
import org.jgroups.blocks.GroupRequest;
import org.jgroups.blocks.RspFilter;

class ClusteredTupleBatchCacheLoader extends AbstractCacheLoader {
  private StripedLock lock = new StripedLock();
  private TupleBatchCacheLoaderConfig config;
  private CommandsFactory commandsFactory;

  private boolean init = false;

  @Override
  public void start() {
    init();
  }

  private void init() {
    if (!this.init) {
      setCommandsFactory(cache.getComponentRegistry().getComponent(CommandsFactory.class));
      this.init = true;
    }
  }

  /**
   * A test to check whether the cache is in its started state. If not, calls
   * should not be made as the channel may not have properly started, blocks
   * due to state transfers may be in progress, etc.
   *
   * @return true if the cache is in its STARTED state.
   */
  protected boolean isCacheReady() {
    return cache.getCacheStatus() == CacheStatus.STARTED;
  }

  @Inject
  public void setCommandsFactory(CommandsFactory commandsFactory) {
    this.commandsFactory = commandsFactory;
  }

  /**
   * Sets the configuration. A property <code>timeout</code> is used as the
   * timeout value.
   */
  public void setConfig(IndividualCacheLoaderConfig base) {
    this.config = (TupleBatchCacheLoaderConfig) base;
  }

  public IndividualCacheLoaderConfig getConfig() {
    return config;
  }

  public Set getChildrenNames(Fqn fqn) throws Exception {
    return Collections.emptySet();
  }

  private List<Object> callRemote(DataCommand dataCommand) throws Exception {
    ClusteredGetCommand clusteredGet = commandsFactory  .buildClusteredGetCommand(false, dataCommand);
    List resps;
    // JBCACHE-1186
    resps = cache.getRPCManager().callRemoteMethods(null,  clusteredGet, GroupRequest.GET_ALL, config.getTimeout(), new ResponseValidityFilter(cache.getMembers(), cache.getLocalAddress(), dataCommand), false);

    if (resps == null) {
      throw new ReplicationException("No replies to call " + dataCommand  + ".  Perhaps we're alone in the cluster?"); //$NON-NLS-1$ //$NON-NLS-2$
    }
   
    return resps;
  }

  public Map get(Fqn name) throws Exception {
    return get0(name);
  }

  protected Map get0(Fqn name) throws Exception {
    // DON'T make a remote call if this is a remote call in the first place
    // - leads to deadlocks - JBCACHE-1103
    if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) {
      return null;
    }
    // return Collections.emptyMap();
    lock.acquireLock(name, true);
    try {
      init();
      GetDataMapCommand command = commandsFactory.buildGetDataMapCommand(name);
      List resps = callRemote(command);
     
      Map result = Collections.EMPTY_MAP;
      for (Object o:resps) {
        if (o != null && !(o instanceof Exception)) {
          List clusteredGetResp = (List) o;
          if ((Boolean)clusteredGetResp.get(0)) {
            Map resp = (Map)clusteredGetResp.get(1);
            if (!resp.isEmpty()) {
              result = resp;
            }
          }
        }
      }     
      return result;
    } finally {
      lock.releaseLock(name);
    }
  }

  public boolean exists(Fqn name) throws Exception {
    // DON'T make a remote call if this is a remote call in the first place
    // - leads to deadlocks - JBCACHE-1103
    if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) {
      return false;
    }

    lock.acquireLock(name, false);
    try {
      init();
      ExistsCommand command = commandsFactory.buildExistsNodeCommand(name);
      List resps = callRemote(command);
      boolean result = false;
      for (Object o:resps) {
        if (o != null && !(o instanceof Exception)) {
          List<Boolean> clusteredGetResp = (List<Boolean>) o;
          if (clusteredGetResp.get(0)) {
            if (clusteredGetResp.get(1)) {
              result = true;
              break;
            }
          }
        }
      }
      return result;
    } finally {
      lock.releaseLock(name);
    }
  }

  public Object put(Fqn name, Object key, Object value) throws Exception {
    return null;
  }

  /**
   * Does nothing; replication handles put.
   */
  public void put(Fqn name, Map attributes) throws Exception {
  }

  /**
   * Does nothing; replication handles put.
   */
  @Override
  public void put(List<Modification> modifications) throws Exception {
  }

  /**
   * Fetches the remove value, does not remove. Replication handles removal.
   */
  public Object remove(Fqn name, Object key) throws Exception {
    return null;
  }

  /**
   * Does nothing; replication handles removal.
   */
  public void remove(Fqn name) throws Exception {
    // do nothing
  }

  /**
   * Does nothing; replication handles removal.
   */
  public void removeData(Fqn name) throws Exception {
  }

  /**
   * Does nothing.
   */
  @Override
  public void prepare(Object tx, List modifications, boolean one_phase)
      throws Exception {
  }

  /**
   * Does nothing.
   */
  @Override
  public void commit(Object tx) throws Exception {
  }

  /**
   * Does nothing.
   */
  @Override
  public void rollback(Object tx) {
  }

  @Override
  public void loadEntireState(ObjectOutputStream os) throws Exception {
    // intentional no-op
  }

  @Override
  public void loadState(Fqn subtree, ObjectOutputStream os) throws Exception {
    // intentional no-op
  }

  @Override
  public void storeEntireState(ObjectInputStream is) throws Exception {
    // intentional no-op
  }

  @Override
  public void storeState(Fqn subtree, ObjectInputStream is) throws Exception {
    // intentional no-op
  }

  @Override
  public void setRegionManager(RegionManager manager) {
  }

  public static class ResponseValidityFilter implements RspFilter {
    private int numValidResponses = 0;
    private List<Address> pendingResponders;
    private DataCommand command;

    public ResponseValidityFilter(List<Address> expected,Address localAddress, DataCommand command) {
      this.pendingResponders = new ArrayList<Address>(expected);
      // We'll never get a response from ourself
      this.pendingResponders.remove(localAddress);
      this.command = command;
    }

    public boolean isAcceptable(Object object, Address address) {
      pendingResponders.remove(address);

      if (object instanceof List) {
        List response = (List) object;
        Boolean foundResult = (Boolean) response.get(0);
        if (foundResult) {
          if (command instanceof ExistsCommand) {
            Boolean resp = (Boolean)response.get(1);
            if (resp) {
              numValidResponses++;   
            }
          }
          else if (command instanceof GetDataMapCommand) {
            Map resp = (Map)response.get(1);
            if (!resp.isEmpty()) {
              numValidResponses++;
            }
          }
        }
      }
      // always return true to make sure a response is logged by the
      // JGroups RpcDispatcher.
      return true;
    }

    public boolean needMoreResponses() {
      return numValidResponses < 1 && pendingResponders.size() > 0;
    }

  }
}
TOP

Related Classes of org.teiid.cache.jboss.ClusteredTupleBatchCacheLoader$ResponseValidityFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.