001/*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.coprocessor;
021
022import org.apache.hadoop.conf.Configuration;
023import org.apache.hadoop.hbase.Coprocessor;
024import org.apache.hadoop.hbase.CoprocessorEnvironment;
025import org.apache.hadoop.hbase.util.VersionInfo;
026import org.apache.yetus.audience.InterfaceAudience;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.io.IOException;
031
032/**
033 * Encapsulation of the environment of each coprocessor
034 */
035@InterfaceAudience.Private
036public class BaseEnvironment<C extends Coprocessor> implements CoprocessorEnvironment<C> {
037  private static final Logger LOG = LoggerFactory.getLogger(BaseEnvironment.class);
038
039  /** The coprocessor */
040  public C impl;
041  /** Chaining priority */
042  protected int priority = Coprocessor.PRIORITY_USER;
043  /** Current coprocessor state */
044  Coprocessor.State state = Coprocessor.State.UNINSTALLED;
045  private int seq;
046  private Configuration conf;
047  private ClassLoader classLoader;
048
049  /**
050   * Constructor
051   * @param impl the coprocessor instance
052   * @param priority chaining priority
053   */
054  public BaseEnvironment(final C impl, final int priority, final int seq, final Configuration conf) {
055    this.impl = impl;
056    this.classLoader = impl.getClass().getClassLoader();
057    this.priority = priority;
058    this.state = Coprocessor.State.INSTALLED;
059    this.seq = seq;
060    this.conf = new ReadOnlyConfiguration(conf);
061  }
062
063  /** Initialize the environment */
064  public void startup() throws IOException {
065    if (state == Coprocessor.State.INSTALLED ||
066        state == Coprocessor.State.STOPPED) {
067      state = Coprocessor.State.STARTING;
068      Thread currentThread = Thread.currentThread();
069      ClassLoader hostClassLoader = currentThread.getContextClassLoader();
070      try {
071        currentThread.setContextClassLoader(this.getClassLoader());
072        impl.start(this);
073        state = Coprocessor.State.ACTIVE;
074      } finally {
075        currentThread.setContextClassLoader(hostClassLoader);
076      }
077    } else {
078      LOG.warn("Not starting coprocessor " + impl.getClass().getName() +
079          " because not inactive (state=" + state.toString() + ")");
080    }
081  }
082
083  /** Clean up the environment */
084  public void shutdown() {
085    if (state == Coprocessor.State.ACTIVE) {
086      state = Coprocessor.State.STOPPING;
087      Thread currentThread = Thread.currentThread();
088      ClassLoader hostClassLoader = currentThread.getContextClassLoader();
089      try {
090        currentThread.setContextClassLoader(this.getClassLoader());
091        impl.stop(this);
092        state = Coprocessor.State.STOPPED;
093      } catch (IOException ioe) {
094        LOG.error("Error stopping coprocessor "+impl.getClass().getName(), ioe);
095      } finally {
096        currentThread.setContextClassLoader(hostClassLoader);
097      }
098    } else {
099      LOG.warn("Not stopping coprocessor "+impl.getClass().getName()+
100          " because not active (state="+state.toString()+")");
101    }
102  }
103
104  @Override
105  public C getInstance() {
106    return impl;
107  }
108
109  @Override
110  public ClassLoader getClassLoader() {
111    return classLoader;
112  }
113
114  @Override
115  public int getPriority() {
116    return priority;
117  }
118
119  @Override
120  public int getLoadSequence() {
121    return seq;
122  }
123
124  /** @return the coprocessor environment version */
125  @Override
126  public int getVersion() {
127    return Coprocessor.VERSION;
128  }
129
130  /** @return the HBase release */
131  @Override
132  public String getHBaseVersion() {
133    return VersionInfo.getVersion();
134  }
135
136  @Override
137  public Configuration getConfiguration() {
138    return conf;
139  }
140}