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.replication; 019 020import java.util.ArrayList; 021import java.util.Collections; 022import java.util.List; 023import org.apache.hadoop.hbase.Cell; 024import org.apache.hadoop.hbase.HBaseInterfaceAudience; 025import org.apache.hadoop.hbase.regionserver.wal.WALUtil; 026import org.apache.hadoop.hbase.wal.WAL.Entry; 027import org.apache.yetus.audience.InterfaceAudience; 028 029/** 030 * A {@link WALEntryFilter} which contains multiple filters and applies them in chain order 031 */ 032@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.REPLICATION) 033public class ChainWALEntryFilter implements WALEntryFilter { 034 035 private final WALEntryFilter[] filters; 036 private WALCellFilter[] cellFilters; 037 038 public ChainWALEntryFilter(WALEntryFilter... filters) { 039 this.filters = filters; 040 initCellFilters(); 041 } 042 043 public ChainWALEntryFilter(List<WALEntryFilter> filters) { 044 ArrayList<WALEntryFilter> rawFilters = new ArrayList<>(filters.size()); 045 // flatten the chains 046 for (WALEntryFilter filter : filters) { 047 if (filter instanceof ChainWALEntryFilter) { 048 Collections.addAll(rawFilters, ((ChainWALEntryFilter) filter).filters); 049 } else { 050 rawFilters.add(filter); 051 } 052 } 053 this.filters = rawFilters.toArray(new WALEntryFilter[rawFilters.size()]); 054 initCellFilters(); 055 } 056 057 public void initCellFilters() { 058 ArrayList<WALCellFilter> cellFilters = new ArrayList<>(filters.length); 059 for (WALEntryFilter filter : filters) { 060 if (filter instanceof WALCellFilter) { 061 cellFilters.add((WALCellFilter) filter); 062 } 063 } 064 this.cellFilters = cellFilters.toArray(new WALCellFilter[cellFilters.size()]); 065 } 066 067 @Override 068 public Entry filter(Entry entry) { 069 entry = filterEntry(entry); 070 if (entry == null) { 071 return null; 072 } 073 074 filterCells(entry); 075 return entry; 076 } 077 078 protected Entry filterEntry(Entry entry) { 079 for (WALEntryFilter filter : filters) { 080 if (entry == null) { 081 return null; 082 } 083 entry = filter.filter(entry); 084 } 085 return entry; 086 } 087 088 protected void filterCells(Entry entry) { 089 if (entry == null || cellFilters.length == 0) { 090 return; 091 } 092 WALUtil.filterCells(entry.getEdit(), c -> filterCell(entry, c)); 093 } 094 095 private Cell filterCell(Entry entry, Cell cell) { 096 for (WALCellFilter filter : cellFilters) { 097 cell = filter.filterCell(entry, cell); 098 if (cell == null) { 099 break; 100 } 101 } 102 return cell; 103 } 104}