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.coprocessor;
019
020import java.io.IOException;
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.hbase.Coprocessor;
023import org.apache.hadoop.hbase.CoprocessorEnvironment;
024import org.apache.hadoop.hbase.util.VersionInfo;
025import org.apache.yetus.audience.InterfaceAudience;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029/**
030 * Encapsulation of the environment of each coprocessor
031 */
032@InterfaceAudience.Private
033public class BaseEnvironment<C extends Coprocessor> implements CoprocessorEnvironment<C> {
034  private static final Logger LOG = LoggerFactory.getLogger(BaseEnvironment.class);
035
036  /** The coprocessor */
037  public C impl;
038  /** Chaining priority */
039  protected int priority = Coprocessor.PRIORITY_USER;
040  /** Current coprocessor state */
041  Coprocessor.State state = Coprocessor.State.UNINSTALLED;
042  private int seq;
043  private Configuration conf;
044  private ClassLoader classLoader;
045
046  /**
047   * Constructor
048   * @param impl     the coprocessor instance
049   * @param priority chaining priority
050   */
051  public BaseEnvironment(final C impl, final int priority, final int seq,
052    final Configuration conf) {
053    this.impl = impl;
054    this.classLoader = impl.getClass().getClassLoader();
055    this.priority = priority;
056    this.state = Coprocessor.State.INSTALLED;
057    this.seq = seq;
058    this.conf = new ReadOnlyConfiguration(conf);
059  }
060
061  /** Initialize the environment */
062  public void startup() throws IOException {
063    if (state == Coprocessor.State.INSTALLED || state == Coprocessor.State.STOPPED) {
064      state = Coprocessor.State.STARTING;
065      Thread currentThread = Thread.currentThread();
066      ClassLoader hostClassLoader = currentThread.getContextClassLoader();
067      try {
068        currentThread.setContextClassLoader(this.getClassLoader());
069        impl.start(this);
070        state = Coprocessor.State.ACTIVE;
071      } finally {
072        currentThread.setContextClassLoader(hostClassLoader);
073      }
074    } else {
075      LOG.warn("Not starting coprocessor " + impl.getClass().getName()
076        + " because not inactive (state=" + state.toString() + ")");
077    }
078  }
079
080  /** Clean up the environment */
081  public void shutdown() {
082    if (state == Coprocessor.State.ACTIVE) {
083      state = Coprocessor.State.STOPPING;
084      Thread currentThread = Thread.currentThread();
085      ClassLoader hostClassLoader = currentThread.getContextClassLoader();
086      try {
087        currentThread.setContextClassLoader(this.getClassLoader());
088        impl.stop(this);
089        state = Coprocessor.State.STOPPED;
090      } catch (IOException ioe) {
091        LOG.error("Error stopping coprocessor " + impl.getClass().getName(), ioe);
092      } finally {
093        currentThread.setContextClassLoader(hostClassLoader);
094      }
095    } else {
096      LOG.warn("Not stopping coprocessor " + impl.getClass().getName()
097        + " because not active (state=" + state.toString() + ")");
098    }
099  }
100
101  @Override
102  public C getInstance() {
103    return impl;
104  }
105
106  @Override
107  public ClassLoader getClassLoader() {
108    return classLoader;
109  }
110
111  @Override
112  public int getPriority() {
113    return priority;
114  }
115
116  @Override
117  public int getLoadSequence() {
118    return seq;
119  }
120
121  /** Returns the coprocessor environment version */
122  @Override
123  public int getVersion() {
124    return Coprocessor.VERSION;
125  }
126
127  /** Returns the HBase release */
128  @Override
129  public String getHBaseVersion() {
130    return VersionInfo.getVersion();
131  }
132
133  @Override
134  public Configuration getConfiguration() {
135    return conf;
136  }
137}