MigrationManager
package com.truegames.ldapmigration;
import com.truegames.ldapmigration.dao.TGIPersonDao;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.LdapAttributes;
import org.springframework.ldap.ldif.batch.LdifAggregator;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.truegames.ldapmigration.Group.*;
import static com.truegames.ldapmigration.dao.TGIPersonDao.*;
/**
* Source user:
* -------------------------------------------------------------------
* mail: email@mail.com
* birthDate: 05/21/1970
* displayName: DISPLAYNAME
* userPassword: [B@442f1e75
* objectClass: top
* objectClass: inetOrgPerson
* sn: someSN
* cn: someCN
* createTimestamp: 20091013210906Z (becomes registrationDate)
* <p/>
* <p/>
* Destination ldif file:
* -------------------------------------------------------------------
* <p/>
* -----User Entries
* email: email@mail.com
* birthday: 19700521000000Z (convert format, change to birthday, create birthday when missing.)
* uid: 51 (new incremented)
* userPassword: [B@442f1e75 (preserve - SHA)
* objectClass: top
* objectClass: person (create new objectClass entries)
* objectClass: tgiPerson
* sn=sn: someSN
* cn=cn: someCN
* <p/>
* -----Game Account Entries
* dn: cn=aGame,cn=someCN,ou=Users,dc=games,dc=truegames,dc=com
* cn: aGame
* displayName: DISPLAYNAME
* objectClass: tgiGameAccount
* objectClass: top
* registrationDate: 20091013210906Z
* banned: FALSE
* <p/>
* -----Group Entry
* dn: cn=aGroup,cn=aGame,ou=Groups,dc=games,dc=truegames,dc=com
* objectClass: top
* objectClass: groupOfNames
* cn: aGroup
* member: cn=default,ou=Users,dc=games,dc=truegames,dc=com
* member: cn=callsign,ou=Users,dc=games,dc=truegames,dc=com
* member: cn= -etc- ,ou=Users,dc=games,dc=truegames,dc=com
*/
public class MigrationManager {
@Autowired
private TGIPersonDao tgiPersonDao;
@Autowired
private FlatFileItemWriter<String> writer;
@Qualifier("list1")
@Autowired
private ClassPathResource list1List;
@Qualifier("list2")
@Autowired
private ClassPathResource list2List;
@Qualifier("list3")
@Autowired
private ClassPathResource list3List;
@Qualifier("list4")
@Autowired
private ClassPathResource list4List;
@Qualifier("noBirthdayList")
@Autowired
private FileSystemResource noBirthdayList;
@Qualifier("userNotFoundList")
@Autowired
private FileSystemResource userNotFoundList;
private int uidCounter = 51;
private final String CR = System.getProperty("line.separator");
public void testOneLikeMigrate(String name, Group group) throws Exception {
writeNamesToLdif(Collections.singletonList(name), "ldif-testOneLikeMigrate.txt", group);
}
public void testOne(String name) throws ParseException, NamingException, IOException {
if (true) {
throw new OperationNotSupportedException("Need Group entry");
}
List<String> ldapEntriesList = new ArrayList<String>();
LdifAggregator ldifAggregator = new LdifAggregator();
NamingEnumeration<? extends Attribute> ldapAttributes = tgiPersonDao.getSourceAttributes(name);
LdapAttributes tgiPerson = new LdapAttributes(tgiPersonDao.buildDnWithBase(name));
LdapAttributes tgiGameAccount = new LdapAttributes(tgiPersonDao.buildGameAccountDnWithBase(name));
process(ldapAttributes, tgiPerson, tgiGameAccount);
ldapEntriesList.add(ldifAggregator.aggregate(tgiPerson));
ldapEntriesList.add(ldifAggregator.aggregate(tgiGameAccount));
}
public void migrate() throws Exception {
writeNamesToLdif(getTthNames(), "out/ldif-1.txt", enum1);
writeNamesToLdif(getMmorpgNames(), "out/ldif-2.txt", enum2);
writeNamesToLdif(getChampsNames(), "out/ldif-3.txt", enum3);
writeNamesToLdif(getOriginalsNames(), "out/ldif-4.txt", enum4);
}
public void writeNamesToLdif(List<String> names, String ldifFilename, Group group) throws Exception {
String header = "-----------------------------------------------------------------------------" + CR + "GROUP: " + group.getGroupName() + CR;
System.out.println(header);
FileUtils.writeStringToFile(userNotFoundList.getFile(), header);
FileUtils.writeStringToFile(noBirthdayList.getFile(), header);
int numNamesAttempted = 0;
int numNamesFound = 0;
List<String> ldapEntriesList = new ArrayList<String>();
LdifAggregator ldifAggregator = new LdifAggregator();
List<String> commonNames = new ArrayList<String>();
for (String name : names) {
if (++numNamesAttempted % 100 == 0) {
System.out.print(numNamesFound + "/" + numNamesAttempted + " ");
}
NamingEnumeration<? extends Attribute> ldapAttributes;
try {
ldapAttributes = tgiPersonDao.getSourceAttributes(name);
} catch (NameNotFoundException nnfe) {
FileUtils.writeLines(userNotFoundList.getFile(), Collections.singletonList(nnfe.getMessage()));
continue;
}
LdapAttributes tgiPerson = new LdapAttributes(tgiPersonDao.buildDnWithBase(name));
LdapAttributes tgiGameAccount = new LdapAttributes(tgiPersonDao.buildGameAccountDnWithBase(name));
process(ldapAttributes, tgiPerson, tgiGameAccount);
// need this for the groupEntry below
commonNames.add((String) tgiPerson.get(firstName).get());
ldapEntriesList.add(ldifAggregator.aggregate(tgiPerson));
ldapEntriesList.add(ldifAggregator.aggregate(tgiGameAccount));
uidCounter++;
numNamesFound++;
}
System.out.print("Final (found/attempted): " + numNamesFound + "/" + numNamesAttempted + " ");
LdapAttributes groupEntry = new LdapAttributes(tgiPersonDao.buildGroupDnWithBase(group.getGroupName()));
processGroupEntry(groupEntry, group, commonNames);
ldapEntriesList.add(ldifAggregator.aggregate(groupEntry));
writer.setResource(new FileSystemResource(ldifFilename));
writer.open(new ExecutionContext());
writer.write(ldapEntriesList);
writer.close();
}
private void processGroupEntry(LdapAttributes groupEntry, Group group, List<String> names) {
// objectClass:
BasicAttribute objectClassAttr = new BasicAttribute(objectClass, groupObjectClasses[0]);
objectClassAttr.add(groupObjectClasses[1]);
groupEntry.put(objectClassAttr);
// member:
BasicAttribute memberAttr = new BasicAttribute(member);
memberAttr.add("cn=default,ou=Users,dc=games,dc=truegames,dc=com"); // default user
for (String name : names) {
memberAttr.add("cn=" + name + ",ou=Users,dc=games,dc=truegames,dc=com");
}
groupEntry.put(memberAttr);
// cn:
groupEntry.put(firstName, group.getGroupName());
}
public List<String> getTthNames() throws IOException {
return readNames(list2List.getFile());
}
public List<String> getMmorpgNames() throws IOException {
return readNames(list1List.getFile());
}
public List<String> getChampsNames() throws IOException {
return readNames(list3List.getFile());
}
public List<String> getOriginalsNames() throws IOException {
return readNames(list4List.getFile());
}
private void process(NamingEnumeration<? extends Attribute> attributes, LdapAttributes tgiPerson, LdapAttributes tgiGameAccount) throws
ParseException,
NamingException,
IOException {
SimpleDateFormat sourceSdf = new SimpleDateFormat("MM/dd/yyyy");
SimpleDateFormat destSdf = new SimpleDateFormat("yyyyMMddHHmmss");
String firstNameCache = "UNSET";
while (attributes.hasMoreElements()) {
Attribute attribute = attributes.nextElement();
try {
if (objectClass.equals(attribute.getID())) {
BasicAttribute objectClassAttr = new BasicAttribute(objectClass, tgiPersonObjectClasses[0]);
objectClassAttr.add(tgiPersonObjectClasses[1]);
objectClassAttr.add(tgiPersonObjectClasses[2]);
tgiPerson.put(objectClassAttr);
objectClassAttr = new BasicAttribute(objectClass, tgiGameAccountObjectClasses[0]);
objectClassAttr.add(tgiGameAccountObjectClasses[1]);
tgiGameAccount.put(objectClassAttr);
}
else if (displayName.equals(attribute.getID())) {
tgiGameAccount.put(attribute.getID(), attribute.get());
}
else if (firstName.equals(attribute.getID())) {
tgiPerson.put(attribute.getID(), attribute.get());
tgiGameAccount.put(attribute.getID(), "game1");
firstNameCache = attribute.get().toString();
}
// apply create timestamp to registration date
else if (createTimestamp.equals(attribute.getID())) {
tgiGameAccount.put(registrationDate, attribute.get());
}
else if (birthDate.equals(attribute.getID()) || birthDay.equals(attribute.getID())) {
// MM/dd/yyyy yyyy MM dd HHmm ssZ
// 05/10/1970 -> 1970 05 10 0000 00Z
tgiPerson.put(attribute.getID(), destSdf.format(sourceSdf.parse(attribute.get().toString())) + "Z");
}
// tgiPerson only. Pass these through
else if (lastName.equals(attribute.getID()) || userPassword.equals(attribute.getID())) {
tgiPerson.put(attribute.getID(), attribute.get());
}
// tgiPerson only. Change "mail" to "email"
else if (mail.equals(attribute.getID())) {
tgiPerson.put(email, attribute.get());
}
tgiGameAccount.put(banned, "FALSE");
tgiPerson.put(uid, uidCounter);
} catch (NamingException e) {
e.printStackTrace();
}
}
// Check for the birthday. If it hasn't been set yet...
if (tgiPerson.get(birthDay) == null && tgiPerson.get(birthDate) == null) {
FileUtils.writeLines(noBirthdayList.getFile(), Collections.singletonList(firstNameCache));
tgiPerson.put(birthDay, destSdf.format(sourceSdf.parse("01/01/1997")) + "Z"); // 13 as of Jan 1, 2010, which means Jan 1, 1997
}
}
private List<String> readNames(File resource) throws IOException {
BufferedReader in = null;
ArrayList<String> names = new ArrayList<String>();
try {
in = new BufferedReader(new FileReader(resource));
String line;
while ((line = in.readLine()) != null) {
if (!StringUtils.isBlank(line)) {
names.add(line);
}
}
} finally {
if (in != null) {
in.close();
}
}
return names;
}
public void setTgiPersonDao(TGIPersonDao tgiPersonDao) {
this.tgiPersonDao = tgiPersonDao;
}
public void setWriter(FlatFileItemWriter<String> writer) {
this.writer = writer;
}
public void setList1List(ClassPathResource list1List) {
this.list1List = list1List;
}
public void setList2List(ClassPathResource list2List) {
this.list2List = list2List;
}
public void setList3List(ClassPathResource list3List) {
this.list3List = list3List;
}
public void setList4List(ClassPathResource list4List) {
this.list4List = list4List;
}
public void setNoBirthdayList(FileSystemResource noBirthdayList) {
this.noBirthdayList = noBirthdayList;
}
public void setUserNotFoundList(FileSystemResource userNotFoundList) {
this.userNotFoundList = userNotFoundList;
}
}