blob: 996b55c3bc8ecece3598a2768ee14af92b5850e1 [file] [log] [blame]
/*
* 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.
*
*/
package org.apache.kerby;
import org.apache.directory.mavibot.btree.BTree;
import org.apache.directory.mavibot.btree.BTreeFactory;
import org.apache.directory.mavibot.btree.BTreeTypeEnum;
import org.apache.directory.mavibot.btree.KeyCursor;
import org.apache.directory.mavibot.btree.PersistedBTreeConfiguration;
import org.apache.directory.mavibot.btree.RecordManager;
import org.apache.directory.mavibot.btree.Tuple;
import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
import org.apache.directory.mavibot.btree.serializer.StringSerializer;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.identity.backend.AbstractIdentityBackend;
import org.apache.kerby.kerberos.kerb.request.KrbIdentity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A backend based on Apache Mavibot(an MVCC BTree library).
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class MavibotBackend extends AbstractIdentityBackend {
//Name of the database
private static final String DATA_TREE = "kerby-data";
// Name of the database file
private static final String DATABASE_NAME = "kerby-data.db";
private static final Logger LOG = LoggerFactory.getLogger(MavibotBackend.class);
//The RecordManager of Mavibot
private RecordManager rm;
//The BTree holding all data
private BTree<String, KrbIdentity> database;
/**
* Creates a new instance of MavibotBackend.
*
* @param location
* the File handle pointing to the database file or the directory
* where it is present
* @throws Exception e
*/
public MavibotBackend(File location) throws Exception {
String dbPath = location.getAbsolutePath();
LOG.info("Initializing the mavibot backend");
if (!location.exists() && !location.mkdirs()) {
throw new KrbException("Can't create location file");
}
if (location.isDirectory()) {
dbPath += File.separator + DATABASE_NAME;
}
rm = new RecordManager(dbPath);
if (rm.getManagedTrees().contains(DATA_TREE)) {
database = rm.getManagedTree(DATA_TREE);
} else {
PersistedBTreeConfiguration<String, KrbIdentity> config =
new PersistedBTreeConfiguration<String, KrbIdentity>();
// _no_ duplicates
config.setAllowDuplicates(false);
config.setBtreeType(BTreeTypeEnum.PERSISTED);
config.setFilePath(dbPath);
config.setKeySerializer(StringSerializer.INSTANCE);
config.setName(DATA_TREE);
config.setValueSerializer(KrbIdentitySerializer.INSTANCE);
database = BTreeFactory.createPersistedBTree(config);
rm.manage(database);
}
}
/**
* {@inheritDoc}
*/
@Override
protected Iterable<String> doGetIdentities() throws KrbException {
List<String> keys = new ArrayList<>();
KeyCursor<String> cursor = null;
try {
cursor = database.browseKeys();
while (cursor.hasNext()) {
keys.add(cursor.next());
}
} catch (Exception e) {
throw new KrbException("Errors occurred while fetching the principals", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return keys;
}
/**
* {@inheritDoc}
*/
@Override
protected KrbIdentity doGetIdentity(String principalName) throws KrbException {
try {
return database.get(principalName);
} catch (KeyNotFoundException e) {
LOG.debug("Identity {} doesn't exist", principalName);
return null;
} catch (IOException e) {
throw new KrbException("Failed to get the identity " + principalName);
}
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized KrbIdentity doAddIdentity(KrbIdentity identity) throws KrbException {
String p = identity.getPrincipalName();
try {
if (database.hasKey(p)) {
throw new KrbException("Identity already exists " + p);
}
return database.insert(p, identity);
} catch (KeyNotFoundException e) {
throw new KrbException("No such identity exists " + p);
} catch (IOException e) {
throw new KrbException("Failed to add the identity " + p);
}
}
/**
* {@inheritDoc}
*/
@Override
protected synchronized KrbIdentity doUpdateIdentity(KrbIdentity identity) throws KrbException {
String p = identity.getPrincipalName();
try {
if (!database.hasKey(p)) {
throw new KrbException("No identity found with the principal " + p);
}
database.delete(p);
return database.insert(p, identity);
} catch (Exception e) {
throw new KrbException("Failed to update the identity " + p);
}
}
/**
* {@inheritDoc}
*/
@Override
protected void doDeleteIdentity(String principalName) throws KrbException {
try {
Tuple<String, KrbIdentity> t = database.delete(principalName);
if (t == null) {
throw new KrbException("Not existing, identity = " + principalName);
}
} catch (IOException e) {
throw new KrbException("Failed to delete the identity " + principalName);
}
}
/**
* {@inheritDoc}
*/
@Override
protected void doStop() throws KrbException {
try {
rm.close();
} catch (IOException e) {
throw new KrbException("Failed to close the database", e);
}
}
}