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,   *
013     * software distributed under the License is distributed on an  *
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015     * KIND, either express or implied.  See the License for the    *
016     * specific language governing permissions and limitations      *
017     * under the License.                                           *
018     ****************************************************************/
019    package org.apache.james.domainlist.hbase;
020    
021    import java.io.IOException;
022    import java.util.ArrayList;
023    import java.util.List;
024    
025    import org.apache.hadoop.hbase.client.Delete;
026    import org.apache.hadoop.hbase.client.Get;
027    import org.apache.hadoop.hbase.client.HTable;
028    import org.apache.hadoop.hbase.client.Put;
029    import org.apache.hadoop.hbase.client.Result;
030    import org.apache.hadoop.hbase.client.ResultScanner;
031    import org.apache.hadoop.hbase.client.Scan;
032    import org.apache.hadoop.hbase.util.Bytes;
033    import org.apache.james.domainlist.api.DomainListException;
034    import org.apache.james.domainlist.hbase.def.HDomainList;
035    import org.apache.james.domainlist.lib.AbstractDomainList;
036    import org.apache.james.system.hbase.TablePool;
037    import org.slf4j.Logger;
038    import org.slf4j.LoggerFactory;
039    
040    /**
041     * Implementation of the DomainList for a HBase persistence.
042     */
043    public class HBaseDomainList extends AbstractDomainList {
044    
045        /**
046         * The Logger.
047         */
048        private static Logger log = LoggerFactory.getLogger(HBaseDomainList.class.getName());
049    
050        /**
051         * @see org.apache.james.domainlist.api.DomainList#containsDomain(String)
052         */
053        @Override
054        public boolean containsDomain(String domain) throws DomainListException {
055            HTable table = null;
056            try {
057                table = TablePool.getInstance().getDomainlistTable();
058                Get get = new Get(Bytes.toBytes(domain));
059                Result result = table.get(get);
060                if (! result.isEmpty()) {
061                    return true;
062                }
063            } catch (IOException e) {
064                log.error("Error while counting domains from HBase", e);
065                throw new DomainListException("Error while counting domains from HBase", e);
066            } finally {
067                if (table != null) {
068                    try {
069                        TablePool.getInstance().putTable(table);
070                    } catch (IOException e) {
071                        // Do nothing, we can't get access to the HBaseSchema.
072                    }
073                }
074            }
075            return false;
076        }
077    
078        /**
079         * @see org.apache.james.domainlist.api.DomainList#addDomain(String)
080         */
081        @Override
082        public void addDomain(String domain) throws DomainListException {
083            String lowerCasedDomain = domain.toLowerCase();
084            if (containsDomain(lowerCasedDomain)) {
085                throw new DomainListException(lowerCasedDomain + " already exists.");
086            }
087            HTable table = null;
088            try {
089                table = TablePool.getInstance().getDomainlistTable();
090                Put put = new Put(Bytes.toBytes(lowerCasedDomain));
091                put.add(HDomainList.COLUMN_FAMILY_NAME, HDomainList.COLUMN.DOMAIN, null);
092                table.put(put);
093                table.flushCommits();
094            } catch (IOException e) {
095                log.error("Error while adding domain in HBase", e);
096                throw new DomainListException("Error while adding domain in HBase", e);
097            } finally {
098                if (table != null) {
099                    try {
100                        TablePool.getInstance().putTable(table);
101                    } catch (IOException e) {
102                        // Do nothing, we can't get access to the HBaseSchema.
103                    }
104                }
105            }
106        }
107    
108        @Override
109        public void removeDomain(String domain) throws DomainListException {
110            HTable table = null;
111            try {
112                table = TablePool.getInstance().getDomainlistTable();
113                Delete delete = new Delete(Bytes.toBytes(domain));
114                table.delete(delete);
115                table.flushCommits();
116            } catch (IOException e) {
117                log.error("Error while deleting user from HBase", e);
118                throw new DomainListException("Error while deleting domain from HBase", e);
119            } finally {
120                if (table != null) {
121                    try {
122                        TablePool.getInstance().putTable(table);
123                    } catch (IOException e) {
124                        // Do nothing, we can't get access to the HBaseSchema.
125                    }
126                }
127            }
128        }
129    
130        /**
131         * @see org.apache.james.domainlist.lib.AbstractDomainList#getDomainListInternal()
132         */
133        @Override
134        protected List<String> getDomainListInternal() throws DomainListException {
135            List<String> list = new ArrayList<String>();
136            HTable table = null;
137            ResultScanner resultScanner = null;
138            try {
139                table = TablePool.getInstance().getDomainlistTable();
140                Scan scan = new Scan();
141                scan.addFamily(HDomainList.COLUMN_FAMILY_NAME);
142                scan.setCaching(table.getScannerCaching() * 2);
143                resultScanner = table.getScanner(scan);
144                Result result = null;
145                while ((result = resultScanner.next()) != null) {
146                    list.add(Bytes.toString(result.getRow()));
147                }
148            } catch (IOException e) {
149                log.error("Error while counting domains from HBase", e);
150                throw new DomainListException("Error while counting domains from HBase", e);
151            } finally {
152                if (resultScanner != null) {
153                    resultScanner.close();
154                }
155                if (table != null) {
156                    try {
157                        TablePool.getInstance().putTable(table);
158                    } catch (IOException e) {
159                        // Do nothing, we can't get access to the HBaseSchema.
160                    }
161                }
162            }
163            return list;
164        }
165    
166    }