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.util;
019
020/**
021 * CacheableIPList loads a list of subnets from a file.
022 * The list is cached and the cache can be refreshed by specifying cache timeout.
023 * A negative value of cache timeout disables any caching.
024 *
025 * Thread safe.
026 */
027
028public class CacheableIPList implements IPList {
029  private final long cacheTimeout;
030  private volatile long cacheExpiryTimeStamp;
031  private volatile FileBasedIPList ipList;
032
033  public CacheableIPList(FileBasedIPList ipList, long cacheTimeout) {
034    this.cacheTimeout =  cacheTimeout;
035    this.ipList = ipList;
036    updateCacheExpiryTime();
037  }
038
039  /**
040   * Reloads the ip list
041   */
042  private  void  reset() {
043    ipList = ipList.reload();
044    updateCacheExpiryTime();
045  }
046
047  private void updateCacheExpiryTime() {
048    if (cacheTimeout < 0) {
049      cacheExpiryTimeStamp = -1; // no automatic cache expiry.
050    }else {
051      cacheExpiryTimeStamp = System.currentTimeMillis() + cacheTimeout;
052    }
053  }
054
055  /**
056   * Refreshes the ip list
057   */
058  public  void refresh () {
059    cacheExpiryTimeStamp = 0;
060  }
061
062  @Override
063  public boolean isIn(String ipAddress) {
064    //is cache expired
065    //Uses Double Checked Locking using volatile
066    if (cacheExpiryTimeStamp >= 0 && cacheExpiryTimeStamp < System.currentTimeMillis()) {
067      synchronized(this) {
068        //check if cache expired again
069        if (cacheExpiryTimeStamp < System.currentTimeMillis()) {
070          reset();
071        }
072      }
073    }
074    return ipList.isIn(ipAddress);
075  }
076}