package org.nishen.alma.toolkit.tasks;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.ServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;
import org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException;
import org.nishen.alma.toolkit.entity.user.ObjectFactory;
import org.nishen.alma.toolkit.entity.user.User;
import org.nishen.alma.toolkit.entity.user.UserIdentifier;
import org.nishen.alma.toolkit.entity.user.UserIdentifier.IdType;
import org.nishen.alma.toolkit.entity.ws.Error;
import org.nishen.alma.toolkit.entity.ws.WebServiceResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
/**
* Task to correct the Identifiers of a User record.
*
* @author nishen
*/
public class TaskFixUserIdentifiers implements Task
{
private static final Logger log = LoggerFactory.getLogger(TaskFixUserIdentifiers.class);
private static final String TASKNAME = "fixUserIdentifiers";
private String userListFilename = null;
private String identifiersFilename = null;
private String cnFilename = null;
private ObjectFactory of = new ObjectFactory();
private Provider<WebTarget> webTargetProvider;
@Inject
private TaskFixUserIdentifiers(@Named("app.cmdline") final String[] args,
@Named("app.config") final Properties config,
@Named("ws.url.alma") Provider<WebTarget> webTargetProvider)
{
// extract relevant command line arguments
if (args != null && args.length > 0)
for (int x = 0; x < args.length; x++)
{
if (args[x].equals("-ids"))
{
if (args.length > (x + 1))
identifiersFilename = args[++x];
}
else if (args[x].equals("-users"))
{
if (args.length > (x + 1))
userListFilename = args[++x];
}
else if (args[x].equals("-cns"))
{
if (args.length > (x + 1))
cnFilename = args[++x];
}
}
this.webTargetProvider = webTargetProvider;
log.debug("initialised {}", this.getClass().getCanonicalName());
}
@Override
public void run()
{
log.info("executing task: {}", this.getClass().getSimpleName());
Map<String, String> identifiers = null;
Map<String, String> cns = null;
List<String> userList = null;
if (userListFilename == null)
{
log.error("user list filename required.");
return;
}
if (identifiersFilename == null)
{
log.error("identifiers filename required.");
return;
}
if (cnFilename == null)
{
log.error("cn filename required.");
return;
}
try
{
File userListFile = new File(userListFilename);
userList = getUserList(userListFile);
File idFile = new File(identifiersFilename);
identifiers = getIdentifiers(idFile);
File cnFile = new File(cnFilename);
cns = getCnCaseMapping(cnFile);
}
catch (FileNotFoundException nfe)
{
log.error("cannot find or open file: {}", nfe.getMessage(), nfe);
return;
}
WebTarget target = webTargetProvider.get();
for (String oldPrimaryId : userList)
{
try
{
log.info("processing user: {}", oldPrimaryId);
String newPrimaryId = identifiers.get(oldPrimaryId.toLowerCase());
if (newPrimaryId == null)
{
log.warn("user partyId not found: {}", oldPrimaryId);
continue;
}
String oneId = cns.get(oldPrimaryId.toLowerCase());
if (oneId == null)
oneId = oldPrimaryId;
WebTarget t = target.path(oldPrimaryId);
User user = t.request(MediaType.APPLICATION_XML_TYPE).get(User.class);
log.info("fetched user: {}", user.getPrimaryId());
// remove PARTY_ID, ONE_ID, INSTITUTION_ID
boolean hasPartyId = false;
List<UserIdentifier> idsToRemove = new ArrayList<UserIdentifier>(5);
for (UserIdentifier i : user.getUserIdentifiers().getUserIdentifier())
{
if ("PARTY_ID".equals(i.getIdType().getValue()))
{
hasPartyId = true;
idsToRemove.add(i);
}
if ("ONE_ID".equals(i.getIdType().getValue()))
idsToRemove.add(i);
if ("INST_ID".equals(i.getIdType().getValue()))
idsToRemove.add(i);
// log.info("identifiers [{}]: {}", i.getIdType().getValue(), i.getValue());
}
for (UserIdentifier i : idsToRemove)
user.getUserIdentifiers().getUserIdentifier().remove(i);
JAXBElement<User> jaxbUser = null;
// save with oldPrimaryId to eliminate PartyId
if (hasPartyId)
{
jaxbUser = of.createUser(user);
user = t.request(MediaType.APPLICATION_XML).put(Entity.entity(jaxbUser, MediaType.APPLICATION_XML),
User.class);
log.info("updated user - removed PartyID: {}", user.getPrimaryId());
}
// add new primaryId, oneId
IdType idType = of.createUserIdentifierIdType();
idType.setValue("ONE_ID");
idType.setDesc("ONE_ID");
UserIdentifier userIdentifier = of.createUserIdentifier();
userIdentifier.setIdType(idType);
userIdentifier.setStatus("ACTIVE");
userIdentifier.setValue(oneId);
user.getUserIdentifiers().getUserIdentifier().add(userIdentifier);
user.setPrimaryId(newPrimaryId);
// save with oldPrimaryId
jaxbUser = of.createUser(user);
user = t.request(MediaType.APPLICATION_XML).put(Entity.entity(jaxbUser, MediaType.APPLICATION_XML),
User.class);
log.info("updated user - changed PrimaryID: {} -> {}", oldPrimaryId, user.getPrimaryId());
}
catch (ClientErrorException cee)
{
try
{
WebServiceResult error = cee.getResponse().readEntity(WebServiceResult.class);
for (Error e : error.getErrorList().getError())
{
String mesg = e.getErrorMessage();
if (mesg != null)
mesg = mesg.replaceAll("\n", " ");
}
}
catch (MessageBodyProviderNotFoundException e)
{
String error = cee.getResponse().readEntity(String.class);
Object[] args = new Object[] { oldPrimaryId, error };
log.error("TaskFixUserIdentifiers[{}] error: {}", args);
}
}
catch (ServerErrorException see)
{
Object[] args = new Object[] { oldPrimaryId, see.getResponse().getStatusInfo().getStatusCode(),
see.getMessage() };
log.error("TaskFixUserIdentifiers[{}] {}: {}", args);
}
catch (Exception e)
{
Object[] args = new Object[] { oldPrimaryId, e.getMessage(), e };
log.error("TaskFixUserIdentifiers[{}]: {}", args);
}
}
}
@Override
public Map<String, String> getUsageOptions()
{
Map<String, String> options = new HashMap<String, String>();
options.put("-cns filename", "Common Names from AD");
options.put("-users filename", "list of user identifiers to process");
options.put("-ids filename", "list of OneID mappings to PartyID");
return options;
}
private Map<String, String> getIdentifiers(File file) throws FileNotFoundException
{
Map<String, String> result = new HashMap<String, String>(600000);
Scanner scanner = null;
scanner = new Scanner(file);
scanner.nextLine(); // header line
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
if (line == null || "".equals(line))
continue;
String[] parts = line.split(",");
if (parts == null || parts.length < 2)
continue;
result.put(parts[0].toLowerCase(), parts[1]);
}
scanner.close();
return result;
}
private List<String> getUserList(File file) throws FileNotFoundException
{
List<String> result = new ArrayList<String>(50000);
Scanner scanner = null;
scanner = new Scanner(file);
scanner.nextLine(); // header line
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
if (line == null || "".equals(line))
continue;
String[] parts = line.split(",");
if (parts == null || parts.length < 1)
continue;
result.add(parts[0]);
}
scanner.close();
return result;
}
private Map<String, String> getCnCaseMapping(File file) throws FileNotFoundException
{
Map<String, String> result = new HashMap<String, String>(300000);
Scanner scanner = null;
scanner = new Scanner(file);
scanner.nextLine(); // header line
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
if (line == null || "".equals(line))
continue;
result.put(line.toLowerCase(), line);
}
scanner.close();
return result;
}
public static String getTaskName()
{
return TASKNAME;
}
}