diff --git a/src/main/java/to/rtc/rtc2jira/exporter/jira/JiraExporter.java b/src/main/java/to/rtc/rtc2jira/exporter/jira/JiraExporter.java index 4ca8e1b..a51b6f6 100644 --- a/src/main/java/to/rtc/rtc2jira/exporter/jira/JiraExporter.java +++ b/src/main/java/to/rtc/rtc2jira/exporter/jira/JiraExporter.java @@ -38,6 +38,7 @@ public class JiraExporter implements Exporter { private JiraRestAccess restAccess; private Map> existingIssueTypes; Optional projectOptional; + private int highestExistingId = -1; @Override public boolean isConfigured() { @@ -49,42 +50,42 @@ public void initialize(Settings settings, StorageEngine store) throws Exception this.settings = settings; this.store = store; restAccess = new JiraRestAccess(settings.getJiraUrl(), settings.getJiraUser(), settings.getJiraPassword()); - this.projectOptional = getProject(); ClientResponse response = restAccess.get("/myself"); - if (response.getStatus() == Status.OK.getStatusCode()) { - } else { - System.err.println("Unable to connect to jira repository: " + response.toString()); + if (response.getStatus() != Status.OK.getStatusCode()) { + throw new RuntimeException("Unable to connect to jira repository: " + response.toString()); } - } - - - private boolean forceCreate() { - return settings.isForceCreate(); + this.projectOptional = getProject(); } @Override public void createOrUpdateItem(ODocument item) throws Exception { - String id = StorageQuery.getField(item, FieldNames.JIRA_ID_LINK, ""); - if (forceCreate() || id.isEmpty()) { - createItem(item); - } else { - Date modified = StorageQuery.getField(item, FieldNames.MODIFIED, Date.from(Instant.now())); - Date lastExport = StorageQuery.getField(item, FieldNames.JIRA_EXPORT_TIMESTAMP, new Date(0)); - if (modified.compareTo(lastExport) > 0) { - updateItem(item); - } + String workItemId = item.field(FieldNames.ID); + ensureWorkItemWithId(Integer.parseInt(workItemId)); + Date modified = StorageQuery.getField(item, FieldNames.MODIFIED, Date.from(Instant.now())); + Date lastExport = StorageQuery.getField(item, FieldNames.JIRA_EXPORT_TIMESTAMP, new Date(0)); + if (modified.compareTo(lastExport) > 0) { + updateItem(item); } } - void createItem(ODocument item) throws Exception { - projectOptional.ifPresent(project -> { - Issue issue = createIssueFromWorkItem(item, project); - Issue jiraIssue = createIssueInJira(issue); - if (jiraIssue != null) { - storeReference(jiraIssue, item); - storeTimestampOfLastExport(item); - } - }); + private void ensureWorkItemWithId(int workItemId) { + while (highestExistingId < workItemId) { + createDummyIssues(); + } + } + + private void createDummyIssues() { + if (projectOptional.isPresent()) { + Project project = projectOptional.get(); + Issue issue = new Issue(); + issue.getFields().setProject(project); + issue.getFields().setIssuetype(getIssueType("Task", project)); + issue.getFields().setSummary("Dummy"); + issue.getFields().setDescription("This is just a dummy issue. Delete it after successfully migrating to Jira."); + Issue createdIssue = createIssueInJira(issue); + String highestAsString = createdIssue.getKey().replace(settings.getJiraProjectKey() + '-', ""); + highestExistingId = Integer.parseInt(highestAsString); + } } private void updateItem(ODocument item) { @@ -92,6 +93,7 @@ private void updateItem(ODocument item) { Issue issue = createIssueFromWorkItem(item, project); boolean success = updateIssueInJira(issue); if (success) { + storeReference(issue, item); storeTimestampOfLastExport(item); } }); @@ -187,7 +189,7 @@ Issue createIssueFromWorkItem(ODocument workItem, Project project) { } issueFields.setSummary(issue.getId() + ": " + issueFields.getSummary()); issue.setId(StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, "")); - issue.setKey(StorageQuery.getField(workItem, FieldNames.JIRA_KEY_LINK, "")); + issue.setKey(settings.getJiraProjectKey() + '-' + workItem.field(FieldNames.ID)); return issue; } diff --git a/src/test/java/to/rtc/rtc2jira/exporter/jira/JiraExporterTest.java b/src/test/java/to/rtc/rtc2jira/exporter/jira/JiraExporterTest.java index 0293ac4..adf0492 100644 --- a/src/test/java/to/rtc/rtc2jira/exporter/jira/JiraExporterTest.java +++ b/src/test/java/to/rtc/rtc2jira/exporter/jira/JiraExporterTest.java @@ -2,9 +2,7 @@ import static mockit.Deencapsulation.invoke; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.time.Instant; import java.util.Date; @@ -24,8 +22,6 @@ import to.rtc.rtc2jira.Settings; import to.rtc.rtc2jira.TestDatabaseRule; -import to.rtc.rtc2jira.exporter.jira.entities.Issue; -import to.rtc.rtc2jira.exporter.jira.entities.IssueFields; import to.rtc.rtc2jira.exporter.jira.entities.IssueType; import to.rtc.rtc2jira.exporter.jira.entities.Project; import to.rtc.rtc2jira.storage.FieldNames; @@ -49,8 +45,7 @@ public class JiraExporterTest { public TestDatabaseRule testDbRule = new TestDatabaseRule(); @Test - public void testInitialize(@Mocked ClientResponse clientResponse, @Mocked StorageEngine store) - throws Exception { + public void testInitialize(@Mocked ClientResponse clientResponse, @Mocked StorageEngine store) throws Exception { new Expectations() { { settings.hasJiraProperties(); @@ -76,8 +71,8 @@ public void testInitialize(@Mocked ClientResponse clientResponse, @Mocked Storag } @Test - public void testIsConfigured_serverOK(@Mocked ClientResponse clientResponse, - @Mocked StorageEngine store) throws Exception { + public void testIsConfigured_serverOK(@Mocked ClientResponse clientResponse, @Mocked StorageEngine store) + throws Exception { new Expectations() { { settings.hasJiraProperties(); @@ -102,9 +97,9 @@ public void testIsConfigured_serverOK(@Mocked ClientResponse clientResponse, }; } - @Test - public void testIsConfigured_serverNotOK(@Mocked ClientResponse clientResponse, - @Mocked StorageEngine store) throws Exception { + @Test(expected = RuntimeException.class) + public void testIsConfigured_serverNotOK(@Mocked ClientResponse clientResponse, @Mocked StorageEngine store) + throws Exception { new Expectations() { { settings.hasJiraProperties(); @@ -116,15 +111,14 @@ public void testIsConfigured_serverNotOK(@Mocked ClientResponse clientResponse, }; JiraExporter jiraExporter = new JiraExporter(); + assertTrue(jiraExporter.isConfigured()); jiraExporter.initialize(settings, store); - boolean isConfigured = jiraExporter.isConfigured(); - assertNotEquals(true, isConfigured); } - public void testCreateOrUpdateItem(@Mocked ClientResponse clientResponse, - @Mocked StorageEngine store, @Mocked Repository repoMock, @Mocked RepositoryService service, - @Mocked IssueService issueServiceMock, @Mocked ODocument workItem) throws Exception { + public void testCreateOrUpdateItem_Update(@Mocked ClientResponse clientResponse, @Mocked StorageEngine store, + @Mocked Repository repoMock, @Mocked RepositoryService service, @Mocked IssueService issueServiceMock, + @Mocked ODocument workItem) throws Exception { new Expectations() { { @@ -149,40 +143,10 @@ public void testCreateOrUpdateItem(@Mocked ClientResponse clientResponse, }; } - @Test - public void testCreateOrUpdateItem_forceCreate(@Mocked ODocument workItem, - @Mocked StorageEngine store, @Mocked StorageQuery storageQuery, - @Mocked Optional projectOptional) throws Exception { - - JiraExporter jiraExporter = new JiraExporter(); - - new Expectations(jiraExporter) { - { - settings.hasJiraProperties(); - result = true; - - StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, ""); - result = "123"; - - invoke(jiraExporter, "forceCreate"); - result = true; - } - }; - - jiraExporter.initialize(settings, store); - jiraExporter.createOrUpdateItem(workItem); - - new Verifications() { - { - invoke(jiraExporter, "createItem", workItem); - } - }; - } @Test - public void testCreateOrUpdateItem_itemIdEmpty(@Mocked ODocument workItem, - @Mocked StorageEngine store, @Mocked StorageQuery storageQuery, - @Mocked Optional projectOptional) throws Exception { + public void testCreateOrUpdateItem_CreateWithCorrectId(@Mocked ODocument workItem, @Mocked StorageEngine store, + @Mocked StorageQuery storageQuery, @Mocked Optional projectOptional) throws Exception { JiraExporter jiraExporter = new JiraExporter(); @@ -193,9 +157,6 @@ public void testCreateOrUpdateItem_itemIdEmpty(@Mocked ODocument workItem, StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, ""); result = ""; - - invoke(jiraExporter, "forceCreate"); - result = false; } }; @@ -210,68 +171,10 @@ public void testCreateOrUpdateItem_itemIdEmpty(@Mocked ODocument workItem, }; } - @Test - public void testCreateItem() throws Exception { - - final Project project = new Project(); - final Optional projectOpt = Optional.ofNullable(project); - final StorageEngine engine = testDbRule.getEngine(); - - ODocument workItem = new ODocument(); - workItem.field(FieldNames.DESCRIPTION, "The description"); - - IssueFields fields = new IssueFields(); - fields.setDescription("The description"); - - Issue issue = new Issue(); - issue.setId("123"); - issue.setKey("theKey"); - issue.setFields(fields); - - JiraExporter jiraExporter = new JiraExporter(); - new Expectations(jiraExporter) { - { - - settings.hasJiraProperties(); - result = true; - - invoke(jiraExporter, "getProject"); - result = projectOpt; - minTimes = 1; - - jiraExporter.createIssueFromWorkItem(workItem, withInstanceOf(Project.class)); - result = issue; - jiraExporter.createIssueInJira(issue); - result = issue; - } - }; - jiraExporter.initialize(settings, engine); - - assertEquals("", StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, "")); - assertNull(workItem.field(FieldNames.JIRA_KEY_LINK)); - assertNull(workItem.field(FieldNames.JIRA_EXPORT_TIMESTAMP)); - assertNull(workItem.field(FieldNames.JIRA_EXPORT_TIMESTAMP)); - - jiraExporter.createItem(workItem); - - assertEquals("123", StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, "")); - assertEquals("theKey", workItem.field(FieldNames.JIRA_KEY_LINK)); - assertNotNull(workItem.field(FieldNames.JIRA_EXPORT_TIMESTAMP)); - assertEquals("The description", workItem.field(FieldNames.DESCRIPTION)); - - new Verifications() { - { - jiraExporter.createIssueFromWorkItem(workItem, withInstanceOf(Project.class)); - jiraExporter.createIssueInJira(withInstanceOf(Issue.class)); - jiraExporter.storeReference(withInstanceOf(Issue.class), workItem); - jiraExporter.storeTimestampOfLastExport(workItem); - } - }; - } @Test - public void testCreateOrUpdateItem_notForceCreate(@Mocked ODocument workItem, - @Mocked StorageEngine store, @Mocked StorageQuery storageQuery) throws Exception { + public void testCreateOrUpdateItem(@Mocked ODocument workItem, @Mocked StorageEngine store, + @Mocked StorageQuery storageQuery) throws Exception { JiraExporter jiraExporter = new JiraExporter(); @@ -283,17 +186,14 @@ public void testCreateOrUpdateItem_notForceCreate(@Mocked ODocument workItem, StorageQuery.getField(workItem, FieldNames.JIRA_ID_LINK, ""); result = "123"; - settings.isForceCreate(); - result = false; - StorageQuery.getField(workItem, FieldNames.MODIFIED, withInstanceOf(Date.class)); result = Date.from(Instant.now()); - StorageQuery.getField(workItem, FieldNames.JIRA_EXPORT_TIMESTAMP, - withInstanceOf(Date.class)); + StorageQuery.getField(workItem, FieldNames.JIRA_EXPORT_TIMESTAMP, withInstanceOf(Date.class)); result = new Date(0); - invoke(jiraExporter, "updateItem", workItem); + invoke(jiraExporter, "createIssueInJira"); + invoke(jiraExporter, "updateItem", workItem); } }; @@ -306,5 +206,4 @@ public void testCreateOrUpdateItem_notForceCreate(@Mocked ODocument workItem, } }; } - }