/**
* 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;
import java.util.concurrent.TimeUnit;
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.OrgDBError;
import org.glite.security.voms.admin.integration.orgdb.database.OrgDBSessionFactory;
import org.glite.security.voms.admin.integration.orgdb.model.Participation;
import org.glite.security.voms.admin.integration.orgdb.model.VOMSOrgDBPerson;
import org.glite.security.voms.admin.integration.orgdb.strategies.OrgDBMembershipSynchronizationStrategy;
import org.glite.security.voms.admin.integration.orgdb.strategies.OrgDBMissingMembershipRecordStrategy;
import org.glite.security.voms.admin.integration.orgdb.strategies.OrgDbExpiredParticipationStrategy;
import org.glite.security.voms.admin.persistence.dao.VOMSUserDAO;
import org.glite.security.voms.admin.persistence.model.VOMSUser;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrgDBMembershipSynchronizationTask implements Runnable {
public static final Logger log = LoggerFactory
.getLogger(OrgDBMembershipSynchronizationTask.class);
public static final int UPDATE_COUNT_BATCH = 50;
protected String experimentName;
protected OrgDBMissingMembershipRecordStrategy missingMembershipStrategy;
protected OrgDbExpiredParticipationStrategy expiredParticipationStrategy;
protected OrgDBMembershipSynchronizationStrategy synchronizationStrategy;
public OrgDBMembershipSynchronizationTask(String experiment,
OrgDBMissingMembershipRecordStrategy invalidMembershipStrategy,
OrgDbExpiredParticipationStrategy expiredParticaptionStrategy,
OrgDBMembershipSynchronizationStrategy membershipSynchronizationStrategy) {
experimentName = experiment;
this.missingMembershipStrategy = invalidMembershipStrategy;
this.expiredParticipationStrategy = expiredParticaptionStrategy;
this.synchronizationStrategy = membershipSynchronizationStrategy;
}
protected VOMSOrgDBPerson lookupOrgDBPerson(VOMSUser u, Session s) {
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance()
.getVOMSPersonDAO();
dao.setSession(s);
VOMSOrgDBPerson orgdbPerson = null;
try {
if (u.getOrgDbId() != null) {
orgdbPerson = dao.findById(u.getOrgDbId(), false);
if (orgdbPerson == null) {
log.warn(
"No OrgDB person found for id '{}' linked to VOMS membership {}",
u.getOrgDbId(), u.toString());
}
}
if (orgdbPerson == null) {
log.warn("Looking up orgdb membership by user email address. User: {}",
u.toString());
orgdbPerson = dao.findPersonByEmail(u.getEmailAddress());
}
} catch (Throwable ex) {
log.error("Exception caught while looking up OrgDB user for VOMS user {}",
u);
log.error("Exception caught while looking up OrgDB user: {}",
ex.getMessage(), ex);
orgdbPerson = null;
}
return orgdbPerson;
}
public void run() {
SessionFactory sf = OrgDBSessionFactory.getSessionFactory();
long startTime = System.currentTimeMillis();
try {
if (sf.openSession() == null) {
throw new OrgDBError("Error opening session to OrgDB");
}
sf.getCurrentSession()
.beginTransaction();
ScrollableResults allUserCursor = VOMSUserDAO.instance()
.findAllWithCursor();
int updateCount = 0;
while (allUserCursor.next()) {
OrgDBVOMSPersonDAO dao = OrgDBDAOFactory.instance().getVOMSPersonDAO();
VOMSUser u = (VOMSUser) allUserCursor.get(0);
VOMSOrgDBPerson orgDbPerson = lookupOrgDBPerson(u,
sf.getCurrentSession());
if (orgDbPerson != null) {
updateCount++;
Participation validParticipation = dao.findValidParticipationInExperiment(
orgDbPerson, experimentName);
synchronizationStrategy.synchronizeMemberInformation(u, orgDbPerson,
experimentName, validParticipation);
if (validParticipation == null){
expiredParticipationStrategy.handleOrgDbExpiredParticipation(u,
orgDbPerson, experimentName);
}
// Flush some updates out and release memory
if (updateCount % UPDATE_COUNT_BATCH == 0) {
log.debug("Flushing session after {} updates.", updateCount);
sf.getCurrentSession()
.flush();
sf.getCurrentSession()
.clear();
}
} else {
log.warn("No OrgDB record found for user {}.", u);
missingMembershipStrategy.handleMissingMembershipRecord(u);
}
}
sf.getCurrentSession()
.getTransaction()
.commit();
} catch (OrgDBError e) {
log.error("OrgDB exception caught: {}", e.getMessage());
if (log.isDebugEnabled()) {
log.error("OrgDB exception caught: {}", e.getMessage(), e);
}
try {
sf.getCurrentSession()
.getTransaction()
.rollback();
} catch (Throwable t) {
log.error("Error rolling back OrgDB transaction: {}", t.getMessage(),
t);
}
} finally {
sf.getCurrentSession()
.close();
long elapsedTime = System.currentTimeMillis() - startTime;
log.info("OrgDB synchronization took {} seconds.",
TimeUnit.MILLISECONDS.toSeconds(elapsedTime));
}
}
}