001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.constraint; 019 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.List; 023import java.util.Optional; 024 025import org.apache.yetus.audience.InterfaceAudience; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.apache.hadoop.hbase.Cell; 029import org.apache.hadoop.hbase.CoprocessorEnvironment; 030import org.apache.hadoop.hbase.client.Put; 031import org.apache.hadoop.hbase.client.Durability; 032import org.apache.hadoop.hbase.client.TableDescriptor; 033import org.apache.hadoop.hbase.coprocessor.ObserverContext; 034import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor; 035import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; 036import org.apache.hadoop.hbase.coprocessor.RegionObserver; 037import org.apache.hadoop.hbase.regionserver.InternalScanner; 038import org.apache.hadoop.hbase.wal.WALEdit; 039 040/*** 041 * Processes multiple {@link Constraint Constraints} on a given table. 042 * <p> 043 * This is an ease of use mechanism - all the functionality here could be 044 * implemented on any given system by a coprocessor. 045 */ 046@InterfaceAudience.Private 047public class ConstraintProcessor implements RegionCoprocessor, RegionObserver { 048 049 private static final Logger LOG = LoggerFactory.getLogger(ConstraintProcessor.class); 050 051 private final ClassLoader classloader; 052 053 private List<? extends Constraint> constraints = new ArrayList<>(); 054 055 @Override 056 public Optional<RegionObserver> getRegionObserver() { 057 return Optional.of(this); 058 } 059 060 /** 061 * Create the constraint processor. 062 * <p> 063 * Stores the current classloader. 064 */ 065 public ConstraintProcessor() { 066 classloader = this.getClass().getClassLoader(); 067 } 068 069 @Override 070 public void start(CoprocessorEnvironment environment) { 071 // make sure we are on a region server 072 if (!(environment instanceof RegionCoprocessorEnvironment)) { 073 throw new IllegalArgumentException( 074 "Constraints only act on regions - started in an environment that was not a region"); 075 } 076 RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) environment; 077 TableDescriptor desc = env.getRegion().getTableDescriptor(); 078 // load all the constraints from the HTD 079 try { 080 this.constraints = Constraints.getConstraints(desc, classloader); 081 } catch (IOException e) { 082 throw new IllegalArgumentException(e); 083 } 084 085 if (LOG.isInfoEnabled()) { 086 LOG.info("Finished loading " + constraints.size() 087 + " user Constraints on table: " + desc.getTableName()); 088 } 089 090 } 091 092 @Override 093 public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, 094 WALEdit edit, Durability durability) throws IOException { 095 // check the put against the stored constraints 096 for (Constraint c : constraints) { 097 c.check(put); 098 } 099 // if we made it here, then the Put is valid 100 } 101 102 @Override 103 public boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> e, 104 final InternalScanner s, final Cell curRowCell, final boolean hasMore) throws IOException { 105 // 'default' in RegionObserver might do unnecessary copy for Off heap backed Cells. 106 return hasMore; 107 } 108}