/**
* Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
*
* Licensed 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.glite.security.voms.admin.integration.orgdb.tools;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.glite.security.voms.admin.integration.orgdb.dao.OrgDBDAOFactory;
import org.glite.security.voms.admin.integration.orgdb.dao.OrgDBVOMSPersonDAO;
import org.glite.security.voms.admin.integration.orgdb.database.OrgDBSessionFactory;
import org.glite.security.voms.admin.integration.orgdb.model.Experiment;
import org.glite.security.voms.admin.integration.orgdb.model.Institute;
import org.glite.security.voms.admin.integration.orgdb.model.Participation;
import org.glite.security.voms.admin.integration.orgdb.model.Participation.Id;
import org.glite.security.voms.admin.integration.orgdb.model.VOMSOrgDBPerson;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrgDBUtil {
public static final String EXPERIMENT_NAME = "ATLAS";
public static final String INSTITUTE_CODE = "077630"; // CNAF
public static final Logger log = LoggerFactory.getLogger(OrgDBUtil.class);
protected CommandLineParser parser = new PosixParser();
protected CommandLine commandLine = null;
protected HelpFormatter helpFormatter = new HelpFormatter();
protected Options options = new Options();
protected Command command;
protected String indentSpace = " ";
enum Command {
list,
find,
create,
expire,
restore,
delete,
createFromFile
}
protected void parseCommandLine(String[] args) throws ParseException {
commandLine = parser.parse(options, args);
if (commandLine.hasOption("h"))
printHelpMessageAndExit(0);
if (!commandLine.hasOption("config")) {
log
.error("Please specify the orgDb hibernate configuration using the --config option.");
printHelpMessageAndExit(-1);
}
if (commandLine.getArgs().length == 0) {
log.error("Please specify a command.");
printHelpMessageAndExit(-1);
}
try {
command = Command.valueOf(commandLine.getArgs()[0]);
} catch (IllegalArgumentException e) {
log.error("Unknown command: " + commandLine.getArgs()[0]);
printHelpMessageAndExit(-1);
}
}
private void printHelpMessageAndExit(int i) {
helpFormatter.printHelp("OrgDBUtil", options);
System.exit(i);
}
protected void setupCLParser() {
options.addOption(OptionBuilder.withLongOpt("help")
.withDescription("Displays helps and exits.").create("h"));
options.addOption(OptionBuilder
.withLongOpt("config")
.withDescription(
"Specifies the config to be used to connect to the OrgDB").hasArg()
.create("c"));
options.addOption(OptionBuilder
.withLongOpt("email")
.withDescription(
"Specifies the email to be used when searching/creating users.")
.hasArg().create("email"));
options.addOption(OptionBuilder
.withLongOpt("name")
.withDescription(
"Specifies the name to be used when searching/creating users.")
.hasArg().create("name"));
options.addOption(OptionBuilder
.withLongOpt("surname")
.withDescription(
"Specifies the surname to be used when searching/creating users.")
.hasArg().create("surname"));
options.addOption(OptionBuilder
.withLongOpt("id")
.withDescription(
"Specifies the OrgDB id to be used when searching/creating users.")
.hasArg().create("id"));
options.addOption(OptionBuilder
.withLongOpt("institute")
.withDescription(
"Specifies the OrgDB id to be used when searching/creating users.")
.hasArg().create("institute"));
options.addOption(OptionBuilder
.withLongOpt("experiment")
.withDescription(
"Specifies the OrgDB id to be used when searching/creating users.")
.hasArg().create("experiment"));
options
.addOption(OptionBuilder
.withLongOpt("user_file")
.withDescription(
"A file containing user information to be used when creating multiple users.")
.hasArg().create("user_file"));
options.addOption(OptionBuilder.withLongOpt("verbose")
.withDescription("Produce verbose output.").create("v"));
}
protected String readStringFromConsole() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
protected void printVOMSPerson(VOMSOrgDBPerson person) {
if (commandLine.hasOption("verbose"))
System.out.println(person);
else
System.out.printf("%d %s %s - %s\n", person.getId(),
person.getFirstName(), person.getName(), person.getPhysicalEmail());
for (Participation p : person.getParticipations()) {
if (commandLine.hasOption("verbose"))
System.out.println(p);
else
System.out.printf("%s From: %s To: %s\n", p.getExperiment().getName(),
p.getStartDate(), p.getEndDate());
}
System.out.println("\n");
}
protected void doListUser() {
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
for (VOMSOrgDBPerson p : dao.findAll())
printVOMSPerson(p);
}
protected void printErrorMessageAndExit(String message) {
System.err.println(message);
System.exit(2);
}
protected Long getNewVOMSPersonId(Session s) {
if (s == null || !s.isOpen())
s = OrgDBSessionFactory.getSessionFactory().openSession();
Long id = (Long) s.createQuery("select max(id) from VOMSOrgDBPerson")
.uniqueResult();
return id + 1;
}
protected Participation cloneParticipation(Participation p) {
Participation clone = new Participation();
Id nId = new Id();
nId.setExperimentId(p.getExperiment().getName());
nId.setInstituteId(p.getInstitute().getCode());
clone.setInstitute(p.getInstitute());
clone.setExperiment(p.getExperiment());
clone.setStartDate(new Date());
clone.setEndDate(null);
return clone;
}
protected VOMSOrgDBPerson clonePerson(VOMSOrgDBPerson template, Long id) {
VOMSOrgDBPerson newPerson = new VOMSOrgDBPerson();
newPerson.setId(id);
newPerson.setPhysicalEmail(template.getPhysicalEmail());
newPerson.setEmail(template.getEmail());
newPerson.setInstitute(template.getInstitute());
newPerson.setCernId(template.getCernId());
newPerson.setAtCern(template.getAtCern());
return newPerson;
}
protected String getValueFromConsoleIfOptionUndefined(String optionName)
throws IOException {
String value;
if (!commandLine.hasOption(optionName)) {
System.out.println("Please enter " + optionName + ":");
value = readStringFromConsole();
} else
value = commandLine.getOptionValue(optionName);
return value;
}
protected void updateParticipation(Participation p, Date newEndDate) {
Session s = OrgDBSessionFactory.getSessionFactory().getCurrentSession();
s.getTransaction();
Query q = s
.createSQLQuery("update person_participation set end_date = ? where person_id = ?");
q.setDate(0, newEndDate);
q.setLong(1, p.getVomsPerson().getId());
q.executeUpdate();
s.getTransaction().commit();
}
protected void createParticipation(VOMSOrgDBPerson p, Experiment e,
Institute i) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
Session s = OrgDBSessionFactory.getSessionFactory().getCurrentSession();
s.beginTransaction();
Query q = s
.createSQLQuery("insert into person_participation(EXPERIMENT,INSTITUTE,PERSON_ID,START_DATE) values(?,?,?,?)");
q.setString(0, e.getName());
q.setString(1, i.getCode());
q.setLong(2, p.getId());
q.setDate(3, cal.getTime());
q.executeUpdate();
s.getTransaction().commit();
}
protected Experiment findExperiment(String name) {
Query q = OrgDBSessionFactory.getSessionFactory().openSession()
.createQuery("from Experiment where name = :name");
return (Experiment) q.setString("name", name).uniqueResult();
}
protected Institute findInstitute(String code) {
Query q = OrgDBSessionFactory.getSessionFactory().openSession()
.createQuery("from Institute where code = :code");
return (Institute) q.setString("code", code).uniqueResult();
}
protected void doDelete() {
if (!commandLine.hasOption("id"))
printErrorMessageAndExit("Please provide an id!");
System.out.println("Deleting member with id "
+ commandLine.getOptionValue("id"));
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSOrgDBPerson p = dao.findPersonById(Long.parseLong(commandLine
.getOptionValue("id")));
if (p == null)
printErrorMessageAndExit("No user found for id "
+ commandLine.getOptionValue("id"));
dao.makeTransient(p);
}
protected void doCreateFromFile() throws IOException {
File file = new File(getValueFromConsoleIfOptionUndefined("user_file"));
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
String line = scanner.nextLine();
String[] tokens = line.split(",");
createUser(tokens[1], tokens[2], tokens[4], tokens[5], tokens[6]);
}
scanner.close();
}
protected void createUser(String name, String surname, String email,
String phone, String experiment) {
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
if (dao.findPersonByEmail(email) != null) {
printErrorMessageAndExit("OrgDB already have a user bound to email "
+ email + "!");
}
Experiment e = findExperiment(experiment);
if (e == null)
printErrorMessageAndExit("Experiment "+experiment+" not found");
Institute i = findInstitute(INSTITUTE_CODE);
if (i == null)
printErrorMessageAndExit("Institute not found");
Long newId = getNewVOMSPersonId(null);
VOMSOrgDBPerson newUser = new VOMSOrgDBPerson();
newUser.setId(newId);
newUser.setFirstName(name.toUpperCase());
newUser.setName(surname.toUpperCase());
newUser.setPhysicalEmail(email);
newUser.setEmail(email);
newUser.setAtCern("N");
Calendar cal = Calendar.getInstance();
cal.set(1975, 9, 15);
newUser.setDateOfBirth(cal.getTime());
dao.makePersistent(newUser);
dao.flush();
createParticipation(newUser, e, i);
dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSOrgDBPerson realNew = dao.findById(newId, false);
System.out.println("Created: ");
printVOMSPerson(realNew);
}
protected void doCreate() throws IOException {
String name, surname, email, id, experiment, institute;
name = getValueFromConsoleIfOptionUndefined("name").trim();
surname = getValueFromConsoleIfOptionUndefined("surname").trim();
email = getValueFromConsoleIfOptionUndefined("email").trim();
experiment = getValueFromConsoleIfOptionUndefined("experiment").trim();
createUser(name, surname, email, null, experiment);
}
protected void doExpire() {
if (!commandLine.hasOption("id"))
printErrorMessageAndExit("Please provide an id!");
System.out.println("Expiring member with id "
+ commandLine.getOptionValue("id"));
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSOrgDBPerson p = dao.findPersonById(Long.parseLong(commandLine
.getOptionValue("id")));
if (p == null)
printErrorMessageAndExit("No user found for id "
+ commandLine.getOptionValue("id"));
Participation participation = p
.getValidParticipationForExperiment(EXPERIMENT_NAME);
if (participation == null)
printErrorMessageAndExit("No valid participation found for user " + p);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, -1);
Date newEnd = cal.getTime();
updateParticipation(participation, newEnd);
System.out.println("Member expired.");
findAndPrintUser(p.getId());
}
protected void doFind() {
if (!commandLine.hasOption("email") && !commandLine.hasOption("name")
&& !commandLine.hasOption("surname") && !commandLine.hasOption("id")) {
System.err
.println("Please provide an email or (name,surname) for the search!");
printHelpMessageAndExit(1);
}
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
List<VOMSOrgDBPerson> results = new ArrayList<VOMSOrgDBPerson>();
if (commandLine.hasOption("email")) {
System.out
.println("Searching for " + commandLine.getOptionValue("email"));
VOMSOrgDBPerson p = dao.findPersonByEmail(commandLine
.getOptionValue("email"));
if (p != null)
results.add(p);
}
if (commandLine.hasOption("name") && commandLine.hasOption("surname")) {
System.out.println("Searching for " + commandLine.getOptionValue("name")
+ " " + commandLine.getOptionValue("surname"));
List<VOMSOrgDBPerson> persons = dao.findPersonByName(
commandLine.getOptionValue("name"),
commandLine.getOptionValue("surname"));
results.addAll(persons);
}
if (commandLine.hasOption("id")) {
System.out
.println("Searching for id " + commandLine.getOptionValue("id"));
VOMSOrgDBPerson p = dao.findPersonById(Long.parseLong(commandLine
.getOptionValue("id")));
if (p != null)
results.add(p);
}
System.out.println();
if (results.isEmpty())
System.out.println("No matches found.");
else
for (VOMSOrgDBPerson p : results)
printVOMSPerson(p);
}
protected void execute() throws IOException {
switch (command) {
case list:
doListUser();
break;
case create:
doCreate();
break;
case expire:
doExpire();
break;
case find:
doFind();
break;
case restore:
doRestore();
break;
case delete:
doDelete();
break;
case createFromFile:
doCreateFromFile();
break;
default:
printErrorMessageAndExit("Unimplemented command!");
}
}
public void findAndPrintUser(Long id) {
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSOrgDBPerson p = dao.findPersonById(id);
if (p == null)
System.out.println("No user found with id " + id);
else {
printVOMSPerson(p);
}
}
public void doRestore() {
if (!commandLine.hasOption("id"))
printErrorMessageAndExit("Please provide an id!");
System.out.println("Restoring member with id "
+ commandLine.getOptionValue("id"));
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSOrgDBPerson p = dao.findPersonById(Long.parseLong(commandLine
.getOptionValue("id")));
if (p == null)
printErrorMessageAndExit("No user found for id "
+ commandLine.getOptionValue("id"));
Participation participation = p
.getLastExpiredParticipationForExperiment(EXPERIMENT_NAME);
if (participation == null)
printErrorMessageAndExit("No expired participations found for user " + p);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, 1);
Date newEnd = cal.getTime();
updateParticipation(participation, newEnd);
System.out.println("Member restored.");
findAndPrintUser(p.getId());
}
protected void initializeDatabase() throws FileNotFoundException, IOException {
Properties configProps = new Properties();
configProps.load(new FileReader(commandLine.getOptionValue("config")));
OrgDBSessionFactory.initialize(configProps);
}
public OrgDBUtil(String[] args) throws ParseException, FileNotFoundException,
IOException {
setupCLParser();
parseCommandLine(args);
initializeDatabase();
execute();
Transaction tx = OrgDBSessionFactory.getSessionFactory()
.getCurrentSession().getTransaction();
TransactionStatus status = tx.getStatus();
if (tx.isActive() && !status.equals(TransactionStatus.COMMITTED)
&& !status.equals(TransactionStatus.COMMITTING)){
tx.commit();
}
}
public static void main(String[] args) throws ParseException,
FileNotFoundException, IOException {
new OrgDBUtil(args);
}
}