/*******************************************************************************
$Source: /cvs/repositories/openii3/project/java/examples/org/any_openeai_enterprise/gateways/directoryservice/EnterpriseUserSyncCommand.java,v $
$Revision: 1.3 $
*******************************************************************************/
/**********************************************************************
This file is part of the OpenEAI sample, reference implementation,
and deployment management suite created by Tod Jackson
(tod@openeai.org) and Steve Wheat (steve@openeai.org) at
the University of Illinois Urbana-Champaign.
Copyright (C) 2004 The OpenEAI Software Foundation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For specific licensing details and examples of how this software
can be used to implement integrations for your enterprise, visit
http://www.OpenEai.org/licensing.
*/
package org.any_openeai_enterprise.gateways.directoryservice;
// Core Java
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import javax.jms.JMSException;
import javax.jms.Message;
import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.EnterpriseUser;
import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.NetId;
import org.any_openeai_enterprise.moa.objects.resources.v1_0.LightweightPerson;
import org.jdom.Document;
import org.jdom.Element;
import org.openeai.OpenEaiException;
import org.openeai.config.CommandConfig;
import org.openeai.config.EnterpriseConfigurationObjectException;
import org.openeai.config.EnterpriseFieldException;
import org.openeai.jms.producer.PointToPointProducer;
import org.openeai.layouts.EnterpriseLayoutException;
import org.openeai.moa.EnterpriseObjectQueryException;
import org.openeai.moa.objects.resources.Error;
import com.any_erp_vendor.moa.jmsobjects.person.v1_0.BasicPerson;
import com.any_erp_vendor.moa.objects.resources.v1_0.Name;
//
/**
* This command handles EnterpriseUser Sync messages to apply changes to
* person data to the LDAP directory server.
* <P>
*
*/
public class EnterpriseUserSyncCommand extends DirectoryServiceBase {
/**
* <code>DIRECTORY_SERVICE_PRODUCER</code> uses ProducerConfig with name="DirectoryServiceGatewayProducer".
*/
protected static final String DIRECTORY_SERVICE_PRODUCER = "DirectoryServiceGatewayProducer";
/**
* <code>BASIC_PERSON</code> uses MessageObjectConfig with name="BasicPerson".
*/
protected static final String BASIC_PERSON = "BasicPerson";
/**
* <code>ENTERPRISE_USER</code> uses MessageObjectConfig with name="EnterpriseUser".
*/
protected static final String ENTERPRISE_USER = "EnterpriseUser";
/**
* <code>LIGHTWEIGHT_PERSON</code> uses MessageObjectConfig with name="LightweightPerson".
*/
protected static final String LIGHTWEIGHT_PERSON = "LightweightPerson";
/**
* <code>NET_ID</code> uses MessageObjectConfig with name="NetId".
*/
protected static final String NET_ID = "NetId";
/**
* <code>uidAttr</code> name of the direcotry attribute that is used to form an LDAP distinguished name (DN).
*/
protected String uidAttr = null;
/**
* <code>p2p</code> PointToPointProducer to use for querying BasicPerson.
*/
protected PointToPointProducer p2p;
/**
* Constructor
*
* @param cConfig
* @throws InstantiationException
*/
public EnterpriseUserSyncCommand(CommandConfig cConfig) throws InstantiationException {
super(cConfig);
// Get the enterpriseIdDomain property.
String enterpriseIdDomain = getProperties().getProperty("enterpriseIdDomain", null);
setEnterpriseIdDomain(enterpriseIdDomain.trim());
if (enterpriseIdDomain == null) {
// The enterpriseIdDomain is null, log it an throw an exception.
String errMsg = "Missing 'enterpriseIdDomain' property in the " +
"deployment descriptor. Can't continue.";
logger.fatal("[" + getServiceName() + "] " + errMsg);
throw new InstantiationException(errMsg);
}
logger.info("[" + getServiceName() + "] " + "enterpriseIdDomain is: " + getEnterpriseIdDomain() + ".");
// Set the createMissingUsers property.
if (getProperties().getProperty("createMissingUsers", "false").equalsIgnoreCase("true")) {
setCreateMissingUsers(true);
}
// Get the uid attribute name property
uidAttr = getProperties().getProperty("uidAttributeName");
if (uidAttr == null) {
String errMsg = "uidAttributeName must be set";
logger.fatal("[" + getServiceName() + "] " + errMsg);
throw new InstantiationException(getServiceName() + ".<init>: " + errMsg);
}
// Verify that all message objects required are in AppConfig.
// Get a configured NetId object out of AppConfig.
try {
NetId netId = (NetId)getAppConfig().getObject(NET_ID);
EnterpriseUser entUser = (EnterpriseUser)getAppConfig().getObject(ENTERPRISE_USER);
BasicPerson person = (BasicPerson)getAppConfig().getObject(BASIC_PERSON);
}
catch (EnterpriseConfigurationObjectException eoce) {
// An error occurred retrieving a required object from AppConfig. Log it
// and throw an exception.
String errMsg = "An error occurred retrieving a required object from " +
"AppConfig. The exception is: " + eoce.getMessage();
logger.fatal("[" + getServiceName() + "] " + errMsg);
throw new InstantiationException(errMsg);
}
// Get the producer from AppConfig.
try {
p2p = (PointToPointProducer) getAppConfig().getObject(DIRECTORY_SERVICE_PRODUCER);
logger.info("p2p is "+p2p.getClass());
} catch (EnterpriseConfigurationObjectException e) {
String errMsg = "[" + getServiceName() + "] Error configuring " + DIRECTORY_SERVICE_PRODUCER + ": The exception is: " + e.getMessage();
logger.error(errMsg);
throw new InstantiationException(errMsg);
}
logger.info("[" + getServiceName() + "] instantiated successfully.");
}
/**
* @param messageNumber message number as passed from OpenEAI
* @param aMessage JMS message received
*/
public void execute(int messageNumber, Message aMessage) {
ArrayList errors = new ArrayList();
// Create the input document from the JMS message passed in.
Document inDoc = null;
try {
inDoc = initializeInput(messageNumber, aMessage);
}
catch (JMSException jmse) {
// An error occurred creating the input document from the JMS message
// passed in. Log it and publish a sync error.
publishError ("system", "OpenEAI-2101", "An error occurred creating the input " +
"document from the JMS message passed in. The exception is: " +
jmse.getMessage(), "[" + getServiceName() + ".execute]", jmse);
return;
}
// Get the message metadata.
eControlArea = getControlArea(inDoc.getRootElement());
String messageCategory = eControlArea.getAttribute("messageCategory").getValue();
String messageObject = eControlArea.getAttribute("messageObject").getValue();
String messageRelease = eControlArea.getAttribute("messageRelease").getValue();
String messageAction = eControlArea.getAttribute("messageAction").getValue();
String messageType = eControlArea.getAttribute("messageType").getValue();
logger.info("[" + getServiceName() + ".execute] Received a(n) " + messageCategory + "." + messageObject + "." + messageAction + "-" +
messageType + " (release " + messageRelease + ") message.");
// Verify that this is a message we support.
if (messageObject.equalsIgnoreCase("EnterpriseUser") == false) {
Error error = new Error();
error.setType("application");
error.setErrorNumber("OpenEAI-1002");
error.setErrorDescription("Message object '" + messageObject + "' is not supported.");
errors.add(error);
}
if (messageType.equalsIgnoreCase("Sync") == false) {
Error error = new Error();
error.setType("application");
error.setErrorNumber("OpenEAI-1002");
error.setErrorDescription("Message type '" + messageType + "' is not " + "supported.");
errors.add(error);
}
if (errors.size() > 0) {
ListIterator iterator = errors.listIterator();
while (iterator.hasNext()) {
Error error = (Error)iterator.next();
logger.fatal("[" + getServiceName() + ".execute] " + error.getErrorDescription());
}
publishSyncError(getControlArea(null), errors);
return;
}
if (messageAction.equalsIgnoreCase("Create")) {
handleCreate (messageNumber, aMessage);
}
else {
publishError ("application", "OpenEAI-1002", "Unsupported message action. This command only "
+ "supports an action of 'create'", "[" + getServiceName() + ".execute] ");
}
}
/* (non-Javadoc)
* @see org.any_openeai_enterprise.gateways.directoryservice.DirectoryServiceBase#getServiceName()
*/
protected String getServiceName()
{
return "EnterpriseUserSyncCommand";
}
/**
* @param messageNumber message number as passed from OpenEAI
* @param aMessage JMS message received
*/
protected void handleCreate (int messageNumber, Message aMessage) {
if (getCreateMissingUsers() == false) {
// Application configuration error. This method handles creation of new users in the enterprise
// directory, but a configuration flag preventing creation of mising users was set.
publishError ("application", "OpenEAI-3003", "Application configuration error. " +
"This method handles creation of new users in the enterprise directory, but a configuration flag " +
"preventing creation of mising users was set.", "[" + getServiceName() + "handleCreate]");
return;
}
EnterpriseUser newEntUser = null;
try {
newEntUser = (EnterpriseUser)getAppConfig().getObject(ENTERPRISE_USER);
}
catch (EnterpriseConfigurationObjectException ecoe) {
// An error occurred getting an object from AppConfig. Log it and
// publish a sync error message.
publishError ("application", "OpenEAI-3001", "An error occurred getting an object from " +
"AppConfig. the exception is: " + ecoe.getMessage(), "[" + getServiceName() + ".execute] ", ecoe);
return;
}
// Create the input document from the JMS message passed in.
Document inDoc = null;
try {
inDoc = initializeInput(messageNumber, aMessage);
}
catch (JMSException jmse) {
// An error occurred creating the input document from the JMS message
// passed in. Log it and publish a sync error.
publishError ("system", "OpenEAI-2101", "An error occurred creating the input document from the JMS message passed in. The exception is: " +
jmse.getMessage(), "[" + getServiceName() + ".handleCreate]", jmse);
return;
}
// Get the new state of the BasicPerson and build a BasicPerson object.
Element elemNewEnterpriseUser = inDoc.getRootElement().getChild("DataArea").getChild("NewData").getChild(ENTERPRISE_USER);
try {
newEntUser.buildObjectFromInput(elemNewEnterpriseUser);
}
catch (EnterpriseLayoutException ele) {
// An error occurred building the BasicPerson object from thw
// BasicPerson element contained in the NewData element of
// the message. Log it and publish a sync error message.
publishError ("system", "DirectoryServiceGateway-1002", "An error occurred building the EnterpriseUser object from the EnterpriseUser " +
"element contained in the NewData element of the message. The exception is: " +
ele.getMessage(), "[" + getServiceName() + ".handleCreate] ", ele);
return;
}
NetId netID = newEntUser.getNetId(0);
String principal = netID.getPrincipal();
// If the user entry does not exist in the directory, create it
if (!personExists (uidAttr, principal)) {
if (getCreateMissingUsers())
createPerson (uidAttr, principal);
else {
publishError ("system", "DirectoryServiceGateway-1005", "User does not exist in the directory, but the gateway is configured " +
"to not create missing users. Please change the value of createMissingUsers in the deployment descriptor.",
"[" + getServiceName() + ".handleCreatte] ");
return;
}
}
updateEnterpriseUserInDirectory (newEntUser);
return;
}
/**
* @param entUser EnterpriseUser object representing the user to be updated
* @return
*/
protected boolean updateEnterpriseUserInDirectory(EnterpriseUser entUser) {
boolean success = true;
NetId netID = entUser.getNetId(0);
String principal = netID.getPrincipal();
String enterpriseID = null;
try {
LightweightPerson lightweightPerson = entUser.getLightweightPerson();
enterpriseID = lightweightPerson.getInstitutionalId();
BasicPerson basicPerson = getBasicPerson(enterpriseID);
Name name = basicPerson.getName();
String firstName = name.getFirstName();
String lastName = name.getLastName();
String middleName = name.getMiddleName();
updateName (principal, firstName, lastName, middleName);
List eMails = basicPerson.getEmail();
updateEmail (principal, eMails);
List phones = basicPerson.getPhone();
updatePhone (principal, phones);
} catch (OpenEaiException eaiEx) {
// Publish the sync error.
publishError("system", "DirectoryServiceGateway-1004", "Error while retrieving BasicPerson information for enterprise user '" + enterpriseID
+ ".' The exception is: " + eaiEx.getMessage(), "[" + getServiceName() + ".updateEnterpriseUserInDirectory]", eaiEx);
}
return success;
}
/**
* Retrieves the portal user's BasicPerson object
*
* @param instId
* @return the BasicPerson object or null if it doesn't exist.
* @throws EnterpriseConfigurationObjectException
* @throws EnterpriseFieldException
* @throws EnterpriseObjectQueryException
*/
private BasicPerson getBasicPerson(String instId) throws EnterpriseConfigurationObjectException, EnterpriseFieldException, EnterpriseObjectQueryException {
LightweightPerson lightPerson = (LightweightPerson) getAppConfig().getObject(LIGHTWEIGHT_PERSON);
logger.debug("[" + getServiceName() + "] Got LightweightPerson...");
lightPerson.setInstitutionalId(instId);
logger.debug("[" + getServiceName() + "] Set instid on lightweight person...");
BasicPerson basicPerson = (BasicPerson) getAppConfig().getObject(BASIC_PERSON);
logger.debug("[" + getServiceName() + "] Got " + BASIC_PERSON + " from AppConfig, performing Query...");
List a = basicPerson.query(lightPerson, p2p);
logger.debug("[" + getServiceName() + "] Executed Query...");
if (a.size() == 0) {
logger.debug("[" + getServiceName() + "] No rows found matching the query.");
return null;
} else {
BasicPerson bp = (BasicPerson) a.get(0);
return bp;
}
}
}