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;

}

}