Java tutorial
package org.apache.bookkeeper.meta; /** * 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. */ import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.bookkeeper.replication.ReplicationException; import org.apache.bookkeeper.conf.AbstractConfiguration; import org.apache.bookkeeper.util.ReflectionUtils; import org.apache.commons.configuration.ConfigurationException; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.ZooKeeper; public abstract class LedgerManagerFactory { static final Logger LOG = LoggerFactory.getLogger(LedgerManagerFactory.class); // v1 layout static final int V1 = 1; /** * Return current factory version. * * @return current version used by factory. */ public abstract int getCurrentVersion(); /** * Initialize a factory. * * @param conf * Configuration object used to initialize factory * @param zk * Available zookeeper handle for ledger manager to use. * @param factoryVersion * What version used to initialize factory. * @return ledger manager factory instance * @throws IOException when fail to initialize the factory. */ public abstract LedgerManagerFactory initialize(final AbstractConfiguration conf, final ZooKeeper zk, final int factoryVersion) throws IOException; /** * Uninitialize the factory. * * @throws IOException when fail to uninitialize the factory. */ public abstract void uninitialize() throws IOException; /** * Return the ledger id generator, which is used for global unique ledger id * generation. * * @return ledger id generator. */ public abstract LedgerIdGenerator newLedgerIdGenerator(); /** * return ledger manager for client-side to manage ledger metadata. * * @return ledger manager * @see LedgerManager */ public abstract LedgerManager newLedgerManager(); /** * Return a ledger underreplication manager, which is used to * mark ledgers as unreplicated, and to retrieve a ledger which * is underreplicated so that it can be rereplicated. * * @return ledger underreplication manager * @see LedgerUnderreplicationManager */ public abstract LedgerUnderreplicationManager newLedgerUnderreplicationManager() throws KeeperException, InterruptedException, ReplicationException.CompatibilityException; /** * Create new Ledger Manager Factory. * * @param conf * Configuration Object. * @param zk * ZooKeeper Client Handle, talk to zk to know which ledger manager is used. * @return new ledger manager factory * @throws IOException */ public static LedgerManagerFactory newLedgerManagerFactory(final AbstractConfiguration conf, final ZooKeeper zk) throws IOException, KeeperException, InterruptedException { Class<? extends LedgerManagerFactory> factoryClass; try { factoryClass = conf.getLedgerManagerFactoryClass(); } catch (Exception e) { throw new IOException("Failed to get ledger manager factory class from configuration : ", e); } String ledgerRootPath = conf.getZkLedgersRootPath(); if (null == ledgerRootPath || ledgerRootPath.length() == 0) { throw new IOException("Empty Ledger Root Path."); } // if zk is null, return the default ledger manager if (zk == null) { return new FlatLedgerManagerFactory().initialize(conf, null, FlatLedgerManagerFactory.CUR_VERSION); } LedgerManagerFactory lmFactory; // check that the configured ledger manager is // compatible with the existing layout LedgerLayout layout = LedgerLayout.readLayout(zk, ledgerRootPath); if (layout == null) { // no existing layout lmFactory = createNewLMFactory(conf, zk, factoryClass); return lmFactory.initialize(conf, zk, lmFactory.getCurrentVersion()); } LOG.debug("read ledger layout {}", layout); // there is existing layout, we need to look into the layout. // handle pre V2 layout if (layout.getLayoutFormatVersion() <= V1) { // pre V2 layout we use type of ledger manager @SuppressWarnings("deprecation") String lmType = conf.getLedgerManagerType(); if (lmType != null && !layout.getManagerFactoryClass().equals(lmType)) { throw new IOException("Configured layout " + lmType + " does not match existing layout " + layout.getManagerFactoryClass()); } // create the ledger manager if (FlatLedgerManagerFactory.NAME.equals(layout.getManagerFactoryClass())) { lmFactory = new FlatLedgerManagerFactory(); } else if (HierarchicalLedgerManagerFactory.NAME.equals(layout.getManagerFactoryClass())) { lmFactory = new HierarchicalLedgerManagerFactory(); } else { throw new IOException("Unknown ledger manager type: " + lmType); } return lmFactory.initialize(conf, zk, layout.getManagerVersion()); } // handle V2 layout case if (factoryClass != null && !layout.getManagerFactoryClass().equals(factoryClass.getName())) { throw new IOException("Configured layout " + factoryClass.getName() + " does not match existing layout " + layout.getManagerFactoryClass()); } if (factoryClass == null) { // no factory specified in configuration try { Class<?> theCls = Class.forName(layout.getManagerFactoryClass()); if (!LedgerManagerFactory.class.isAssignableFrom(theCls)) { throw new IOException("Wrong ledger manager factory " + layout.getManagerFactoryClass()); } factoryClass = theCls.asSubclass(LedgerManagerFactory.class); } catch (ClassNotFoundException cnfe) { throw new IOException( "Failed to instantiate ledger manager factory " + layout.getManagerFactoryClass()); } } // instantiate a factory lmFactory = ReflectionUtils.newInstance(factoryClass); return lmFactory.initialize(conf, zk, layout.getManagerVersion()); } /** * Creates the new layout and stores in zookeeper and returns the * LedgerManagerFactory instance. */ private static LedgerManagerFactory createNewLMFactory(final AbstractConfiguration conf, final ZooKeeper zk, Class<? extends LedgerManagerFactory> factoryClass) throws IOException, KeeperException, InterruptedException { String ledgerRootPath = conf.getZkLedgersRootPath(); LedgerManagerFactory lmFactory; LedgerLayout layout; // use default ledger manager factory if no one provided if (factoryClass == null) { // for backward compatibility, check manager type @SuppressWarnings("deprecation") String lmType = conf.getLedgerManagerType(); if (lmType == null) { factoryClass = FlatLedgerManagerFactory.class; } else { if (FlatLedgerManagerFactory.NAME.equals(lmType)) { factoryClass = FlatLedgerManagerFactory.class; } else if (HierarchicalLedgerManagerFactory.NAME.equals(lmType)) { factoryClass = HierarchicalLedgerManagerFactory.class; } else { throw new IOException("Unknown ledger manager type: " + lmType); } } } lmFactory = ReflectionUtils.newInstance(factoryClass); layout = new LedgerLayout(factoryClass.getName(), lmFactory.getCurrentVersion()); try { layout.store(zk, ledgerRootPath); } catch (KeeperException.NodeExistsException nee) { LedgerLayout layout2 = LedgerLayout.readLayout(zk, ledgerRootPath); if (!layout2.equals(layout)) { throw new IOException("Contention writing to layout to zookeeper, " + " other layout " + layout2 + " is incompatible with our " + "layout " + layout); } } return lmFactory; } /** * Format the ledger metadata for LedgerManager * * @param conf * Configuration instance * @param zk * Zookeeper instance */ public void format(final AbstractConfiguration conf, final ZooKeeper zk) throws InterruptedException, KeeperException, IOException { Class<? extends LedgerManagerFactory> factoryClass; try { factoryClass = conf.getLedgerManagerFactoryClass(); } catch (ConfigurationException e) { throw new IOException("Failed to get ledger manager factory class from configuration : ", e); } LedgerLayout layout = LedgerLayout.readLayout(zk, conf.getZkLedgersRootPath()); layout.delete(zk, conf.getZkLedgersRootPath()); // Create new layout information again. createNewLMFactory(conf, zk, factoryClass); } }