package to.rtc.rtc2jira.importer;
import static to.rtc.rtc2jira.storage.FieldNames.ID;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
import to.rtc.rtc2jira.Settings;
import to.rtc.rtc2jira.storage.Attachment;
import to.rtc.rtc2jira.storage.FieldNames;
import to.rtc.rtc2jira.storage.StorageEngine;
import com.ibm.team.links.common.IReference;
import com.ibm.team.repository.client.IItemManager;
import com.ibm.team.repository.client.ILoginHandler2;
import com.ibm.team.repository.client.ILoginInfo2;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.client.internal.ItemManager;
import com.ibm.team.repository.client.login.UsernameAndPasswordLoginInfo;
import com.ibm.team.repository.common.PermissionDeniedException;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.workitem.client.IWorkItemClient;
import com.ibm.team.workitem.common.IWorkItemCommon;
import com.ibm.team.workitem.common.internal.util.SeparatedStringList;
import com.ibm.team.workitem.common.model.IAttribute;
import com.ibm.team.workitem.common.model.IWorkItem;
import com.ibm.team.workitem.common.model.IWorkItemHandle;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
/**
* Imports WorkItems from RTC
*
* @author roman.schaller
*
*/
public class RTCImporter {
private static final Logger LOGGER = Logger.getLogger(RTCImporter.class.getName());
public static final StreamHandler DEFAULT_LOG_HANDLER;
static {
FileHandler fh = null;
try {
fh = new FileHandler("C:/workspace/gitRepRtcToJira/rtc2jira/DefaultImportLog.log");
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
DEFAULT_LOG_HANDLER = fh;
LOGGER.addHandler(DEFAULT_LOG_HANDLER);
}
private Settings settings;
private StorageEngine storageEngine;
private List<Integer> permissionDeniedWorkitems;
private List<Integer> notPresentWorkitems;
private ODocument dryRunDoc;
public RTCImporter(Settings settings, StorageEngine storageEngine) {
this.settings = settings;
this.storageEngine = storageEngine;
this.permissionDeniedWorkitems = new LinkedList<>();
this.notPresentWorkitems = new LinkedList<>();
}
private ODocument getDryRunDoc() {
if (dryRunDoc == null) {
dryRunDoc = new ODocument("WorkItem");
dryRunDoc.field(ID, "dryrun");
dryRunDoc.field(Attachment.EXPORTED_ATTACHMENTS_PROPERTY, new SeparatedStringList());
}
return dryRunDoc;
}
public static boolean isLoginPossible(Settings settings) {
boolean isLoginPossible = false;
if (settings.hasRtcProperties()) {
TeamPlatform.startup();
try {
login(settings).logout();
isLoginPossible = true;
} catch (TeamRepositoryException e) {
LOGGER.log(Level.SEVERE, "Unable to login into RTC Repository", e);
} finally {
TeamPlatform.shutdown();
}
}
return isLoginPossible;
}
public void doImport() {
TeamPlatform.startup();
try {
LOGGER.info("***********************");
LOGGER.info("Starting to import work items.");
ITeamRepository repo = login(settings);
processWorkItems(repo, settings.getRtcWorkItemRange());
repo.logout();
} catch (TeamRepositoryException | IOException e) {
e.printStackTrace();
} finally {
TeamPlatform.shutdown();
}
}
private static ITeamRepository login(Settings settings) throws TeamRepositoryException {
final String userId = settings.getRtcUser();
final String password = settings.getRtcPassword();
String repoUri = settings.getRtcUrl();
final ITeamRepository repo = TeamPlatform.getTeamRepositoryService().getTeamRepository(repoUri);
if (settings.hasProxySettings()) {
repo.setProxy(settings.getProxyHost(), Integer.parseInt(settings.getProxyPort()), null, null);
}
repo.registerLoginHandler(new ILoginHandler2() {
@Override
public ILoginInfo2 challenge(ITeamRepository repo) {
return new UsernameAndPasswordLoginInfo(userId, password);
}
});
repo.registerLoginHandler((ILoginHandler2) loginHandler -> new UsernameAndPasswordLoginInfo(userId, password));
repo.login(null);
return repo;
}
private void processWorkItems(ITeamRepository repo, Iterable<Integer> workItemRange) throws TeamRepositoryException,
IOException {
IWorkItemClient workItemClient = (IWorkItemClient) repo.getClientLibrary(IWorkItemClient.class);
AttachmentHandler attachmentHandler = new AttachmentHandler(repo, storageEngine.getAttachmentStorage());
int counter = 0;
for (Integer currentWorkItemId : workItemRange) {
processWorkItem(repo, workItemClient, currentWorkItemId, attachmentHandler);
LOGGER.info(String.format("processed %s items...", ++counter));
}
LOGGER.info(String.format("There were %s items which I had no permission to access.",
permissionDeniedWorkitems.size()));
for (Integer id : permissionDeniedWorkitems) {
LOGGER.info(String.format("%d, ", id));
}
LOGGER.info(String.format("There were %s items which were not present.", notPresentWorkitems.size()));
for (Integer id : notPresentWorkitems) {
LOGGER.info(String.format("%d, ", id));
}
}
private void processWorkItem(ITeamRepository repo, IWorkItemClient workItemClient, int workItemId,
AttachmentHandler attachmentHandler) throws TeamRepositoryException, IOException {
try {
IWorkItem workItem;
try {
workItem = workItemClient.findWorkItemById(workItemId, IWorkItem.FULL_PROFILE, null);
} catch (PermissionDeniedException e) {
this.permissionDeniedWorkitems.add(workItemId);
return;
}
if (workItem == null) {
this.notPresentWorkitems.add(workItemId);
return;
}
storageEngine.withDB(db -> {
OSQLSynchQuery<ODocument> query = new OSQLSynchQuery<ODocument>("select * from WorkItem where ID = :ID");
List<ODocument> result = db.query(query, workItem.getId());
final ODocument doc;
if (Settings.getInstance().isDryRunImport()) {
doc = getDryRunDoc();
} else if (result.size() > 0) {
doc = result.get(0);
} else {
doc = new ODocument("WorkItem");
doc.field(ID, workItem.getId());
doc.field(Attachment.EXPORTED_ATTACHMENTS_PROPERTY, new SeparatedStringList());
}
saveAttributes(workItemClient, workItem, doc);
attachmentHandler.saveAttachements(workItem);
// handle parent
try {
IWorkItemCommon clientLibrary = (IWorkItemCommon) repo.getClientLibrary(IWorkItemCommon.class);
List<IReference> references;
references =
clientLibrary.resolveWorkItemReferences(workItem, null).getReferences(
com.ibm.team.workitem.common.model.WorkItemEndPoints.PARENT_WORK_ITEM);
if (!references.isEmpty()) {
IReference iReference = references.get(0);
if (iReference.isItemReference()) {
Object resolvedRef = iReference.resolve();
if (resolvedRef instanceof IWorkItemHandle) {
IWorkItemHandle handle = (IWorkItemHandle) resolvedRef;
IItemManager itemManager = repo.itemManager();
IWorkItem completeItem = (IWorkItem) itemManager.fetchCompleteItem(handle, ItemManager.DEFAULT, null);
List<String> itemInfo = new ArrayList<String>();
itemInfo.add("" + completeItem.getId());
itemInfo.add(completeItem.getWorkItemType());
doc.field(FieldNames.PARENT, itemInfo);
}
}
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "A problem occurred while retrieving the item parent", e);
}
if (!Settings.getInstance().isDryRunImport()) {
doc.save();
}
});
} catch (RuntimeException e) {
LOGGER.log(Level.SEVERE, "***** Problem processing workitem " + workItemId, e);
}
}
private void saveAttributes(IWorkItemClient workItemClient, IWorkItem workItem, ODocument doc) {
List<IAttribute> allAttributes;
try {
allAttributes = workItemClient.findAttributes(workItem.getProjectArea(), null);
new AttributeMapper().map(allAttributes, doc, workItem);
} catch (TeamRepositoryException e) {
throw new RuntimeException("Cannot get attributes from project area.", e);
}
}
}