@Override public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException { // check the put against the stored constraints for (Constraint c : constraints) { c.check(put); } // if we made it here, then the Put is valid }
/** * Check to see if the Constraint is currently set. * * @param desc * {@link HTableDescriptor} to check * @param clazz * {@link Constraint} class to check for. * @return <tt>true</tt> if the {@link Constraint} is present, even if it is * disabled. <tt>false</tt> otherwise. */ public static boolean has(HTableDescriptor desc, Class<? extends Constraint> clazz) { return getKeyValueForClass(desc, clazz) != null; }
/** * Write the raw constraint and configuration to the descriptor. * <p> * This method takes care of creating a new configuration based on the passed * in configuration and then updating that with enabled and priority of the * constraint. * <p> * When a constraint is added, it is automatically enabled. */ private static void addConstraint(HTableDescriptor desc, Class<? extends Constraint> clazz, Configuration conf, long priority) throws IOException { writeConstraint(desc, serializeConstraintClass(clazz), configure(conf, true, priority)); }
/** * Add a {@link Constraint} to the table with the given configuration * <p> * Each constraint, when added to the table, will have a specific priority, * dictating the order in which the {@link Constraint} will be run. A * {@link Constraint} added will run on the regionserver before those added to * the {@link HTableDescriptor} later. * * @param desc * table descriptor to the constraint to * @param constraint * to be added * @param conf * configuration associated with the constraint * @throws IOException * if any constraint could not be deserialized. Assumes if 1 * constraint is not loaded properly, something has gone terribly * wrong and that all constraints need to be enforced. */ public static void add(HTableDescriptor desc, Class<? extends Constraint> constraint, Configuration conf) throws IOException { enable(desc); long priority = getNextPriority(desc); addConstraint(desc, constraint, conf, priority++); updateLatestPriority(desc, priority); }
private void checkGroupName(String groupName) throws ConstraintException { if (!groupName.matches("[a-zA-Z0-9_]+")) { throw new ConstraintException("RSGroup name should only contain alphanumeric characters"); } } }
/** * Enable the given {@link Constraint}. Retains all the information (e.g. * Configuration) for the {@link Constraint}, but makes sure that it gets * loaded on the table. * * @param desc * {@link HTableDescriptor} to modify * @param clazz * {@link Constraint} to enable * @throws IOException * If the constraint cannot be properly deserialized */ public static void enableConstraint(HTableDescriptor desc, Class<? extends Constraint> clazz) throws IOException { changeConstraintEnabled(desc, clazz, true); }
/** * Remove the constraint (and associated information) for the table * descriptor. * * @param desc * {@link HTableDescriptor} to modify * @param clazz * {@link Constraint} class to remove */ public static void remove(HTableDescriptor desc, Class<? extends Constraint> clazz) { String key = serializeConstraintClass(clazz); desc.remove(key); }
/** * Read in the configuration from the String encoded configuration * * @param bytes * to read from * @return A valid configuration * @throws IOException * if the configuration could not be read */ private static Configuration readConfiguration(String bytes) throws IOException { return readConfiguration(Bytes.toBytes(bytes)); }
/** * Write the given key and associated configuration to the * {@link HTableDescriptor} */ private static void writeConstraint(HTableDescriptor desc, String key, Configuration conf) throws IOException { // store the key and conf in the descriptor desc.setValue(key, serializeConfiguration(conf)); }
Class<? extends Constraint>... constraints) throws IOException { enable(desc); long priority = getNextPriority(desc); addConstraint(desc, clazz, null, priority++); updateLatestPriority(desc, priority);
@Override public void check(Put p) throws ConstraintException { throw new ConstraintException("AllFailConstraint fails for all puts"); } }
/** * Disable the given {@link Constraint}. Retains all the information (e.g. * Configuration) for the {@link Constraint}, but it just doesn't load the * {@link Constraint} on the table. * * @param desc * {@link HTableDescriptor} to modify * @param clazz * {@link Constraint} to disable. * @throws IOException * if the constraint cannot be found */ public static void disableConstraint(HTableDescriptor desc, Class<? extends Constraint> clazz) throws IOException { changeConstraintEnabled(desc, clazz, false); }
/** * Get the kv {@link Entry} in the descriptor for the specified class * * @param desc {@link HTableDescriptor} to read * @param clazz To search for * @return The {@link Pair} of {@literal <key, value>} in the table, if that class is * present. {@code NULL} otherwise. */ private static Pair<String, String> getKeyValueForClass( HTableDescriptor desc, Class<? extends Constraint> clazz) { // get the serialized version of the constraint String key = serializeConstraintClass(clazz); String value = desc.getValue(key); return value == null ? null : new Pair<>(key, value); }
Pair<Class<? extends Constraint>, Configuration>... constraints) throws IOException { enable(desc); long priority = getNextPriority(desc); for (Pair<Class<? extends Constraint>, Configuration> pair : constraints) { addConstraint(desc, pair.getFirst(), pair.getSecond(), priority++); updateLatestPriority(desc, priority);
@Override public TableDescriptor preModifyTable(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName, TableDescriptor currentDescriptor, TableDescriptor newDescriptor) throws IOException { if (authorizationEnabled) { if (LABELS_TABLE_NAME.equals(tableName)) { throw new ConstraintException("Cannot alter " + LABELS_TABLE_NAME); } } return newDescriptor; }
@Override public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException { if (!authorizationEnabled) { return; } if (LABELS_TABLE_NAME.equals(tableName)) { throw new ConstraintException("Cannot disable " + LABELS_TABLE_NAME); } }
/** * Check passed name. Fail if nulls or if corresponding RSGroupInfo not found. * @return The RSGroupInfo named <code>name</code> */ private RSGroupInfo getAndCheckRSGroupInfo(String name) throws IOException { if (StringUtils.isEmpty(name)) { throw new ConstraintException("RSGroup cannot be null."); } RSGroupInfo rsGroupInfo = getRSGroupInfo(name); if (rsGroupInfo == null) { throw new ConstraintException("RSGroup does not exist: " + name); } return rsGroupInfo; }
@Override public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException { String group = ns.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP); if(group != null && groupAdminServer.getRSGroupInfo(group) == null) { throw new ConstraintException("Region server group "+group+" does not exit"); } }
public void validateTableAndRegionCount(NamespaceDescriptor desc) throws IOException { if (getMaxRegions(desc) <= 0) { throw new ConstraintException( "The max region quota for " + desc.getName() + " is less than or equal to zero."); } if (getMaxTables(desc) <= 0) { throw new ConstraintException( "The max tables quota for " + desc.getName() + " is less than or equal to zero."); } }