@Override public void start(CoprocessorEnvironment environment) { // make sure we are on a region server if (!(environment instanceof RegionCoprocessorEnvironment)) { throw new IllegalArgumentException( "Constraints only act on regions - started in an environment that was not a region"); } RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) environment; HTableDescriptor desc = env.getRegion().getTableDesc(); // load all the constraints from the HTD try { this.constraints = Constraints.getConstraints(desc, classloader); } catch (IOException e) { throw new IllegalArgumentException(e); } if (LOG.isInfoEnabled()) { LOG.info("Finished loading " + constraints.size() + " user Constraints on table: " + desc.getTableName()); } }
@Override public void start(CoprocessorEnvironment env) throws IOException { this.conf = env.getConfiguration(); authorizationEnabled = isAuthorizationSupported(conf); if (!authorizationEnabled) { LOG.warn("The VisibilityController has been loaded with authorization checks disabled."); } if (HFile.getFormatVersion(conf) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) { throw new RuntimeException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS + " is required to persist visibility labels. Consider setting " + HFile.FORMAT_VERSION_KEY + " accordingly."); } if (env instanceof RegionServerCoprocessorEnvironment) { throw new RuntimeException("Visibility controller should not be configured as " + "'hbase.coprocessor.regionserver.classes'."); } // Do not create for master CPs if (!(env instanceof MasterCoprocessorEnvironment)) { visibilityLabelService = VisibilityLabelServiceManager.getInstance() .getVisibilityLabelService(this.conf); } }
@Override public void start(CoprocessorEnvironment env) { this.env = (RegionCoprocessorEnvironment)env; random = new SecureRandom(); conf = env.getConfiguration(); baseStagingDir = SecureBulkLoadUtil.getBaseStagingDir(conf); this.userProvider = UserProvider.instantiate(conf); try { fs = FileSystem.get(conf); fs.mkdirs(baseStagingDir, PERM_HIDDEN); fs.setPermission(baseStagingDir, PERM_HIDDEN); //no sticky bit in hadoop-1.0, making directory nonempty so it never gets erased fs.mkdirs(new Path(baseStagingDir,"DONOTERASE"), PERM_HIDDEN); FileStatus status = fs.getFileStatus(baseStagingDir); if(status == null) { throw new IllegalStateException("Failed to create staging directory"); } if(!status.getPermission().equals(PERM_HIDDEN)) { throw new IllegalStateException( "Directory already exists but permissions aren't set to '-rwx--x--x' "); } } catch (IOException e) { throw new IllegalStateException("Failed to get FileSystem instance",e); } }
@Override public void start(CoprocessorEnvironment environment) { // make sure we are on a region server if (!(environment instanceof RegionCoprocessorEnvironment)) { throw new IllegalArgumentException( "Constraints only act on regions - started in an environment that was not a region"); } RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) environment; HTableDescriptor desc = env.getRegion().getTableDesc(); // load all the constraints from the HTD try { this.constraints = Constraints.getConstraints(desc, classloader); } catch (IOException e) { throw new IllegalArgumentException(e); } if (LOG.isInfoEnabled()) { LOG.info("Finished loading " + constraints.size() + " user Constraints on table: " + new String(desc.getName())); } }
@Override public void start(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; Configuration conf = env.getConfiguration(); // co SequentialIdGeneratorObserver-1-Conf Get environment and configuration instances. this.regionName = env.getRegionInfo().getEncodedName(); String family = conf.get("com.larsgeorge.copro.seqidgen.family", "cf1"); this.family = Bytes.toBytes(family); String qualifier = conf.get("com.larsgeorge.copro.seqidgen.qualifier", // co SequentialIdGeneratorObserver-2-Settings Retrieve the settings passed into the configuration. "GENID"); this.qualifier = Bytes.toBytes(qualifier); int startId = conf.getInt("com.larsgeorge.copro.seqidgen.startId", 1); this.delay = conf.getInt("com.larsgeorge.copro.seqidgen.delay", 100); env.getSharedData().putIfAbsent(KEY_ID, new AtomicInteger(startId)); // co SequentialIdGeneratorObserver-3-Gen Set up generator if this has not been done yet on this region server. } else { LOG.warn("Received wrong context."); } }
@Override public void start(CoprocessorEnvironment env) throws IOException { this.conf = env.getConfiguration(); if (HFile.getFormatVersion(conf) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) { throw new RuntimeException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS + " is required to persist visibility labels. Consider setting " + HFile.FORMAT_VERSION_KEY + " accordingly."); } if (env instanceof RegionServerCoprocessorEnvironment) { throw new RuntimeException("Visibility controller should not be configured as " + "'hbase.coprocessor.regionserver.classes'."); } // Do not create for master CPs if (!(env instanceof MasterCoprocessorEnvironment)) { visibilityLabelService = VisibilityLabelServiceManager.getInstance() .getVisibilityLabelService(this.conf); } Pair<List<String>, List<String>> superUsersAndGroups = VisibilityUtils.getSystemAndSuperUsers(this.conf); this.superUsers = superUsersAndGroups.getFirst(); this.superGroups = superUsersAndGroups.getSecond(); }
@Override public void start(CoprocessorEnvironment env) { // if running at region if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment regionEnv = (RegionCoprocessorEnvironment)env; RpcServerInterface server = regionEnv.getRegionServerServices().getRpcServer(); SecretManager<?> mgr = ((RpcServer)server).getSecretManager(); if (mgr instanceof AuthenticationTokenSecretManager) { secretManager = (AuthenticationTokenSecretManager)mgr; } } }
@Override public void start(CoprocessorEnvironment env) throws IOException { int rmiRegistryPort = -1; int rmiConnectorPort = -1; Configuration conf = env.getConfiguration(); if (env instanceof MasterCoprocessorEnvironment) { // running on Master rmiRegistryPort = conf.getInt("master" + RMI_REGISTRY_PORT_CONF_KEY, defMasterRMIRegistryPort); rmiConnectorPort = conf.getInt("master" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort); LOG.info("Master rmiRegistryPort:" + rmiRegistryPort + ",Master rmiConnectorPort:" + rmiConnectorPort); } else if (env instanceof RegionServerCoprocessorEnvironment) { // running on RegionServer rmiRegistryPort = conf.getInt("regionserver" + RMI_REGISTRY_PORT_CONF_KEY, defRegionserverRMIRegistryPort); rmiConnectorPort = conf.getInt("regionserver" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort); LOG.info("RegionServer rmiRegistryPort:" + rmiRegistryPort + ",RegionServer rmiConnectorPort:" + rmiConnectorPort); } else if (env instanceof RegionCoprocessorEnvironment) { LOG.error("JMXListener should not be loaded in Region Environment!"); return; } synchronized(JMXListener.class) { if (JMX_CS != null) { LOG.info("JMXListener has been started at Registry port " + rmiRegistryPort); } else { startConnectorServer(rmiRegistryPort, rmiConnectorPort); } } }
/** * Create an unmanaged {@link HConnection} based on the environment in which we are running the * coprocessor. The {@link HConnection} must be externally cleaned up (we bypass the usual HTable * cleanup mechanisms since we own everything). * @param env environment hosting the {@link HConnection} * @return an unmanaged {@link HConnection}. * @throws IOException if we cannot create the connection */ public static ClusterConnection getConnectionForEnvironment(CoprocessorEnvironment env) throws IOException { // this bit is a little hacky - just trying to get it going for the moment if (env instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment e = (RegionCoprocessorEnvironment) env; RegionServerServices services = e.getRegionServerServices(); if (services instanceof HRegionServer) { return new CoprocessorHConnection((HRegionServer) services); } } return ConnectionManager.createConnectionInternal(env.getConfiguration()); }
/** * Used to create a parameter to the HServerLoad constructor so that * HServerLoad can provide information about the coprocessors loaded by this * regionserver. * (HBASE-4070: Improve region server metrics to report loaded coprocessors * to master). */ public Set<String> getCoprocessors() { Set<String> returnValue = new TreeSet<String>(); for (CoprocessorEnvironment e: coprocessors) { returnValue.add(e.getInstance().getClass().getSimpleName()); } return returnValue; }
public void shutdown(CoprocessorEnvironment e) { if (e instanceof Environment) { if (LOG.isDebugEnabled()) { LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName()); } ((Environment)e).shutdown(); } else { LOG.warn("Shutdown called on unknown environment: "+ e.getClass().getName()); } }
/** * Find a coprocessor environment by class name * @param className the class name * @return the coprocessor, or null if not found */ public CoprocessorEnvironment findCoprocessorEnvironment(String className) { for (E env: coprocessors) { if (env.getInstance().getClass().getName().equals(className) || env.getInstance().getClass().getSimpleName().equals(className)) { return env; } } return null; }
@Override public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) { if (env1.getPriority() < env2.getPriority()) { return -1; } else if (env1.getPriority() > env2.getPriority()) { return 1; } if (env1.getLoadSequence() < env2.getLoadSequence()) { return -1; } else if (env1.getLoadSequence() > env2.getLoadSequence()) { return 1; } return 0; }
/** * This is used by coprocessor hooks which are declared to throw IOException * (or its subtypes). For such hooks, we should handle throwable objects * depending on the Throwable's type. Those which are instances of * IOException should be passed on to the client. This is in conformance with * the HBase idiom regarding IOException: that it represents a circumstance * that should be passed along to the client for its own handling. For * example, a coprocessor that implements access controls would throw a * subclass of IOException, such as AccessDeniedException, in its preGet() * method to prevent an unauthorized client's performing a Get on a particular * table. * @param env Coprocessor Environment * @param e Throwable object thrown by coprocessor. * @exception IOException Exception */ protected void handleCoprocessorThrowable(final CoprocessorEnvironment env, final Throwable e) throws IOException { if (e instanceof IOException) { throw (IOException)e; } // If we got here, e is not an IOException. A loaded coprocessor has a // fatal bug, and the server (master or regionserver) should remove the // faulty coprocessor from its set of active coprocessors. Setting // 'hbase.coprocessor.abortonerror' to true will cause abortServer(), // which may be useful in development and testing environments where // 'failing fast' for error analysis is desired. if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) { // server is configured to abort. abortServer(env, e); } else { LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment because it threw: " + e,e); coprocessors.remove(env); try { shutdown(env); } catch (Exception x) { LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x); } throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e + "' and has been removed from the active " + "coprocessor set.", e); } }
public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) { if (env1.getPriority() < env2.getPriority()) { return -1; } else if (env1.getPriority() > env2.getPriority()) { return 1; } if (env1.getLoadSequence() < env2.getLoadSequence()) { return -1; } else if (env1.getLoadSequence() > env2.getLoadSequence()) { return 1; } return 0; }
@Override public void start(CoprocessorEnvironment e) { sharedData = ((RegionCoprocessorEnvironment)e).getSharedData(); // using new String here, so that there will be new object on each invocation sharedData.putIfAbsent("test1", new Object()); startCalled = true; }
@Test public void testHTableInterfaceMethods() throws Exception { Configuration conf = util.getConfiguration(); MasterCoprocessorHost cpHost = util.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost(); Class<?> implClazz = DummyRegionObserver.class; cpHost.load(implClazz, Coprocessor.PRIORITY_HIGHEST, conf); CoprocessorEnvironment env = cpHost.findCoprocessorEnvironment(implClazz.getName()); assertEquals(Coprocessor.VERSION, env.getVersion()); assertEquals(VersionInfo.getVersion(), env.getHBaseVersion()); hTableInterface = env.getTable(TEST_TABLE); checkHTableInterfaceMethods(); cpHost.shutdown(env); }
@Override public void start(CoprocessorEnvironment env) throws IOException { if (env instanceof RegionCoprocessorEnvironment) { this.env = (RegionCoprocessorEnvironment)env; return; } throw new CoprocessorException("Must be loaded on a table region!"); }
@Override public void start(CoprocessorEnvironment e) throws IOException { // this only makes sure that leases and locks are available to coprocessors // from external packages RegionCoprocessorEnvironment re = (RegionCoprocessorEnvironment)e; Leases leases = re.getRegionServerServices().getLeases(); leases.createLease(re.getRegion().getRegionInfo().getRegionNameAsString(), 2000, null); leases.cancelLease(re.getRegion().getRegionInfo().getRegionNameAsString()); }
@SuppressWarnings("null") @Override public void start(CoprocessorEnvironment e) throws IOException { // Trigger a NPE to fail the coprocessor Integer i = null; i = i + 1; }
@Override public void start(CoprocessorEnvironment env) throws IOException { if (env instanceof RegionCoprocessorEnvironment) { this.env = (RegionCoprocessorEnvironment) env; } else { throw new CoprocessorException("Must be loaded on a table region!"); } }
@Override public void start(CoprocessorEnvironment e) throws IOException { RegionCoprocessorEnvironment re = (RegionCoprocessorEnvironment) e; if (!re.getSharedData().containsKey(zkkey)) { // there is a short race here // in the worst case we create a watcher that will be notified once re.getSharedData().putIfAbsent( zkkey, new ZKWatcher(re.getRegionServerServices().getZooKeeper() .getRecoverableZooKeeper().getZooKeeper())); } }
@Override public void start(CoprocessorEnvironment env) throws IOException { LOG.info("Starting snapshot filter coprocessor"); conf = env.getConfiguration(); commitTableConf = new HBaseCommitTableConfig(); String commitTableName = conf.get(COMMIT_TABLE_NAME_KEY); if (commitTableName != null) { commitTableConf.setTableName(commitTableName); } commitTableClient = initAndGetCommitTableClient(); snapshotFilter = new SnapshotFilterImpl(commitTableClient); LOG.info("Snapshot filter started"); }
@Override public void start(CoprocessorEnvironment env) throws IOException { LOG.info("Starting compactor coprocessor"); conf = env.getConfiguration(); commitTableConf = new HBaseCommitTableConfig(); String commitTableName = conf.get(COMMIT_TABLE_NAME_KEY); if (commitTableName != null) { commitTableConf.setTableName(commitTableName); } retainNonTransactionallyDeletedCells = conf.getBoolean(HBASE_RETAIN_NON_TRANSACTIONALLY_DELETED_CELLS_KEY, HBASE_RETAIN_NON_TRANSACTIONALLY_DELETED_CELLS_DEFAULT); LOG.info("Compactor coprocessor started"); }
@Override public void stop(CoprocessorEnvironment e) throws IOException { LOG.info("Stopping compactor coprocessor"); if (commitTableClientQueue != null) { for (CommitTable.Client commitTableClient : commitTableClientQueue) { commitTableClient.close(); } } LOG.info("Compactor coprocessor stopped"); }
@Override public void start(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; this.cacheSupplier = getTransactionStateCacheSupplier(env); this.cache = cacheSupplier.get(); HTableDescriptor tableDesc = env.getRegion().getTableDesc(); for (HColumnDescriptor columnDesc : tableDesc.getFamilies()) { String columnTTL = columnDesc.getValue(TxConstants.PROPERTY_TTL); long ttl = 0; if (columnTTL != null) { try { ttl = Long.parseLong(columnTTL); LOG.info("Family " + columnDesc.getNameAsString() + " has TTL of " + columnTTL); } catch (NumberFormatException nfe) { LOG.warn("Invalid TTL value configured for column family " + columnDesc.getNameAsString() + ", value = " + columnTTL); } } ttlByFamily.put(columnDesc.getName(), ttl); } this.allowEmptyValues = getAllowEmptyValues(env, tableDesc); this.txMaxLifetimeMillis = getTxMaxLifetimeMillis(env); this.readNonTxnData = Boolean.valueOf(tableDesc.getValue(TxConstants.READ_NON_TX_DATA)); if (readNonTxnData) { LOG.info("Reading pre-existing data enabled for table " + tableDesc.getNameAsString()); } initializePruneState(env); } }
@Override public void stop(CoprocessorEnvironment e) throws IOException { try { resetPruneState(); } finally { if (cacheSupplier != null) { cacheSupplier.release(); } } }