All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.hbase.kafka.TopicRoutingRules Maven / Gradle / Ivy

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hbase.kafka; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.util.Bytes; import org.apache.yetus.audience.InterfaceAudience; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * The topic routing/drop rules. * * <rules> * <rule .... /> * * </rules> * * * * A wildcard can only be at the beginning or at the end (can be at both sides). * * drop rules are always evaluated first. * * drop examples: * <rule action="drop" table="default:MyTable" /> * Do not send replication events for table MyTable * * <rule action="drop" table="default:MyTable" columnFamily="data"/> * Do not send replication events for table MyTable's column family data * * <rule action="drop" table="default:MyTable" columnFamily="data" qualfier="dhold:*"/> * Do not send replication events for any qualiifier on table MyTable with column family data * * routeRules examples: * * <rule action="routeRules" table="default:MyTable" topic="mytopic"/> * routeRules all replication events for table default:Mytable to topic mytopic * * <rule action="routeRules" table="default:MyTable" columnFamily="data" topic="mytopic"/> * routeRules all replication events for table default:Mytable column family data to topic mytopic * * <rule action="routeRules" table="default:MyTable" columnFamily="data" topic="mytopic" * qualifier="hold:*"/> * routeRules all replication events for qualifiers that start with hold: for table * default:Mytable column family data to topic mytopic */ @InterfaceAudience.Private public class TopicRoutingRules { private List dropRules = new ArrayList<>(); private List routeRules = new ArrayList<>(); private File sourceFile; /** * used for testing */ public TopicRoutingRules() { } /** * construct rule set from file * @param source file that countains the rule set * @throws Exception if load fails */ public TopicRoutingRules(File source) throws Exception { this.sourceFile = source; this.reloadIfFile(); } /** * Reload the ruleset if it was parsed from a file * @throws Exception error loading rule set */ public void reloadIfFile() throws Exception { if (this.sourceFile!=null){ List dropRulesSave = this.dropRules; List routeRulesSave = this.routeRules; try (FileInputStream fin = new FileInputStream(this.sourceFile)) { List dropRulesNew = new ArrayList<>(); List routeRulesNew = new ArrayList<>(); parseRules(fin,dropRulesNew,routeRulesNew); this.dropRules = dropRulesNew; this.routeRules = routeRulesNew; } catch (Exception e){ // roll back this.dropRules=dropRulesSave; this.routeRules=routeRulesSave; // re-throw throw e; } } } /** * parse rules manually from an input stream * @param input InputStream that contains rule text */ public void parseRules(InputStream input) { List dropRulesNew = new ArrayList<>(); List routeRulesNew = new ArrayList<>(); parseRules(input,dropRulesNew,routeRulesNew); this.dropRules = dropRulesNew; this.routeRules = routeRulesNew; } /** * Parse the XML in the InputStream into route/drop rules and store them in the passed in Lists * @param input inputstream the contains the ruleset * @param dropRules list to accumulate drop rules * @param routeRules list to accumulate route rules */ public void parseRules(InputStream input,List dropRules, List routeRules) { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(input); NodeList nodList = doc.getElementsByTagName("rule"); for (int i = 0; i < nodList.getLength(); i++) { if (nodList.item(i) instanceof Element) { parseRule((Element) nodList.item(i),dropRules,routeRules); } } } catch (Exception e) { throw new RuntimeException(e); } } /** * Parse a individual rule from a Element. * @param n the element * @param dropRules list to accumulate drop rules * @param routeRules list to accumulate route rules */ public void parseRule(Element n, List dropRules, List routeRules) { Rule r = null; if (n.getAttribute("action").equals("drop")) { r = new DropRule(); dropRules.add((DropRule) r); } else { r = new TopicRule(n.getAttribute("topic")); routeRules.add((TopicRule) r); } if (n.hasAttribute("table")) { r.setTableName(TableName.valueOf(n.getAttribute("table"))); } if (n.hasAttribute("columnFamily")) { r.setColumnFamily(Bytes.toBytes(n.getAttribute("columnFamily"))); } if (n.hasAttribute("qualifier")) { String qual = n.getAttribute("qualifier"); r.setQualifier(Bytes.toBytes(qual)); } } /** * Indicates if a cell mutation should be dropped instead of routed to kafka. * @param table table name to check * @param columnFamily column family to check * @param qualifer qualifier name to check * @return if the mutation should be dropped instead of routed to Kafka */ public boolean isExclude(final TableName table, final byte []columnFamily, final byte[] qualifer) { for (DropRule r : getDropRules()) { if (r.match(table, columnFamily, qualifer)) { return true; } } return false; } /** * Get topics for the table/column family/qualifier combination * @param table table name to check * @param columnFamily column family to check * @param qualifer qualifier name to check * @return list of topics that match the passed in values (or empty for none). */ public List getTopics(TableName table, byte []columnFamily, byte []qualifer) { List ret = new ArrayList<>(); for (TopicRule r : getRouteRules()) { if (r.match(table, columnFamily, qualifer)) { ret.addAll(r.getTopics()); } } return ret; } /** * returns all the drop rules (used for testing) * @return drop rules */ public List getDropRules() { return dropRules; } /** * returns all the route rules (used for testing) * @return route rules */ public List getRouteRules() { return routeRules; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy