Skip to content

Commit

Permalink
fixup! Fixed RD-15247: IS [NOT] NULL generates wrong JQL
Browse files Browse the repository at this point in the history
wip
  • Loading branch information
bgaidioz committed Dec 31, 2024
1 parent 499b575 commit dc553a4
Show file tree
Hide file tree
Showing 9 changed files with 1,333 additions and 1,203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@
import org.joda.time.DateTimeZone;

import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@SuppressWarnings("unchecked")
public abstract class DASJiraIssueTransformationTable extends DASJiraTable {

private final ZoneId localZoneId;
private final ZoneId remoteZoneId;
DateTimeFormatter offsetTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

protected DASJiraIssueTransformationTable(
Map<String, String> options, String table, String description) {
Map<String, String> options, ZoneId remoteZoneId, String table, String description) {
super(options, table, description);
localZoneId = ZoneId.of(options.get("timezone"));
this.remoteZoneId = remoteZoneId;
}

protected void processFields(
Expand Down Expand Up @@ -59,7 +67,7 @@ protected void processFields(
String created =
maybeFields
.map(f -> f.get(names.get("Created")))
.map(c -> DateTime.parse(c.toString()).withZone(DateTimeZone.UTC).toString())
.map(c -> toLocal(c.toString()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
.orElse(null);
addToRow("created", rowBuilder, created, columns);

Expand Down Expand Up @@ -92,7 +100,11 @@ protected void processFields(
throw new DASSdkApiException("error processing 'description'", e);
}

String due_date = maybeFields.flatMap(f -> Optional.ofNullable(f.get(names.get("Due date")))).map(Object::toString).orElse(null);
String due_date =
maybeFields
.flatMap(f -> Optional.ofNullable(f.get(names.get("Due date"))))
.map(Object::toString)
.orElse(null);

addToRow("due_date", rowBuilder, due_date, columns);

Expand All @@ -117,10 +129,10 @@ protected void processFields(
columns);

String resolved =
maybeFields
.flatMap(f -> Optional.ofNullable(f.get(names.get("Resolved"))))
.map(c -> DateTime.parse(c.toString()).withZone(DateTimeZone.UTC).toString())
.orElse(null);
maybeFields
.flatMap(f -> Optional.ofNullable(f.get(names.get("Resolved"))))
.map(c -> toLocal(c.toString()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
.orElse(null);
addToRow("resolution_date", rowBuilder, resolved, columns);

addToRow(
Expand All @@ -140,7 +152,10 @@ protected void processFields(
addToRow(
"updated",
rowBuilder,
maybeFields.map(f -> f.get(names.get("Updated"))).orElse(null),
maybeFields
.map(f -> f.get(names.get("Updated")))
.map(c -> toLocal(c.toString()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
.orElse(null),
columns);

var componentIds =
Expand Down Expand Up @@ -188,4 +203,10 @@ protected void processFields(
throw new DASSdkApiException(e.getMessage());
}
}

private OffsetDateTime toLocal(String remoteTime) {
return OffsetDateTime.parse(remoteTime, offsetTimeFormatter)
.atZoneSameInstant(localZoneId)
.toOffsetDateTime();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@
import com.rawlabs.protocol.das.Operator;
import com.rawlabs.protocol.das.Qual;
import com.rawlabs.protocol.raw.Value;
import com.rawlabs.protocol.raw.ValueTimestamp;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class DASJiraJqlQueryBuilder {

private final ZoneId zoneId;
private final ZoneId localZoneId;
private final ZoneId remoteZoneId;

public DASJiraJqlQueryBuilder(ZoneId zoneId) {
this.zoneId = zoneId;
public DASJiraJqlQueryBuilder(ZoneId localZoneId, ZoneId remoteZoneId) {
this.localZoneId = localZoneId;
this.remoteZoneId = remoteZoneId;
}

private static final ExtractValueFactory extractValueFactory = new DefaultExtractValueFactory();
Expand Down Expand Up @@ -47,9 +50,19 @@ String mapValue(Value value) {
yield time.toLocalDate().format(DateTimeFormatter.ISO_LOCAL_DATE);
}
case Value v when v.hasTimestamp() -> {
OffsetDateTime time = (OffsetDateTime) extractValueFactory.extractValue(value);
ZonedDateTime dTime =
time.withOffsetSameInstant(ZoneOffset.UTC).atZoneSameInstant(zoneId);
// Without time zone, it's a local time, so we need to set its timezone to the
// local timezone and then convert it to the remote timezone.
ValueTimestamp rawTimestamp = v.getTimestamp();
LocalDateTime time =
LocalDateTime.of(
rawTimestamp.getYear(),
rawTimestamp.getMonth(),
rawTimestamp.getDay(),
rawTimestamp.getHour(),
rawTimestamp.getMinute(),
rawTimestamp.getSecond(),
rawTimestamp.getNano());
ZonedDateTime dTime = time.atZone(localZoneId).withZoneSameInstant(remoteZoneId);
yield dTime.format(formatter);
}
default -> throw new IllegalArgumentException("Unexpected value: " + value);
Expand Down Expand Up @@ -369,19 +382,19 @@ public List<Optional<String>> mkJql(List<Qual> quals) {
// IS NULL and IS NOT NULL are supported.
// IN is supported
if (qual.hasSimpleQual()) {
if (!rawOperator.hasEquals() && !rawOperator.hasNotEquals()) {
jqls.add(Optional.empty());
continue;
}
Value rawValue = qual.getSimpleQual().getValue();
if (rawValue.hasNull()) {
jqls.add(maybeNullCheck(rawOperator).map(p -> "priority " + p));
continue;
}
String operator = mapOperator(rawOperator);
String value = mapValue(rawValue);
String jql = "priority" + " " + operator + " " + value;
jqls.add(Optional.of(jql));
if (!rawOperator.hasEquals() && !rawOperator.hasNotEquals()) {
jqls.add(Optional.empty());
continue;
}
Value rawValue = qual.getSimpleQual().getValue();
if (rawValue.hasNull()) {
jqls.add(maybeNullCheck(rawOperator).map(p -> "priority " + p));
continue;
}
String operator = mapOperator(rawOperator);
String value = mapValue(rawValue);
String jql = "priority" + " " + operator + " " + value;
jqls.add(Optional.of(jql));
} else if (qual.hasListQual()) {
// IN and NOT IN are supported
Optional<String> maybeIn = maybeInCheck(qual.getListQual());
Expand Down Expand Up @@ -439,7 +452,7 @@ public List<Optional<String>> mkJql(List<Qual> quals) {
}
}
} else {
jqls.add(Optional.empty());
jqls.add(Optional.empty());
}
} else if (rawColumn.equals("updated")) {
if (qual.hasSimpleQual()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ public DASJiraTableManager(
com.rawlabs.das.jira.rest.platform.ApiClient apiClientPlatform,
com.rawlabs.das.jira.rest.software.ApiClient apiClientSoftware) {
MyselfApi myselfApi = new MyselfApi(apiClientPlatform);
final ZoneId zoneId;
final ZoneId jiraZoneId;
try {
String jiraTimeZone = myselfApi.getCurrentUser("").getTimeZone();
if (jiraTimeZone == null) {
throw new DASSdkApiException("Couldn't determine JIRA timezone");
}
zoneId = ZoneId.of(jiraTimeZone);
jiraZoneId = ZoneId.of(jiraTimeZone);
} catch (ApiException e) {
throw new DASSdkException("Error getting user timezone", e);
}
tables =
List.of(
new DASJiraAdvancedSettingsTable(options, new JiraSettingsApi(apiClientPlatform)),
new DASJiraBacklogIssueTable(options, new BoardApi(apiClientSoftware)),
new DASJiraBacklogIssueTable(options, jiraZoneId, new BoardApi(apiClientSoftware)),
new DASJiraBoardTable(options, new BoardApi(apiClientSoftware)),
new DASJiraComponentTable(
options,
Expand All @@ -51,19 +51,19 @@ public DASJiraTableManager(
new DASJiraGroupTable(options, new GroupsApi(apiClientPlatform)),
new DASJiraIssueCommentTable(
options,
zoneId,
jiraZoneId,
new IssueCommentsApi(apiClientPlatform),
new IssueSearchApi(apiClientPlatform),
new IssuesApi(apiClientPlatform)),
new DASJiraIssueTable(
options,
zoneId,
jiraZoneId,
new IssueSearchApi(apiClientPlatform),
new IssuesApi(apiClientPlatform)),
new DASJiraIssueTypeTable(options, new IssueTypesApi(apiClientPlatform)),
new DASJiraIssueWorklogTable(
options,
zoneId,
jiraZoneId,
new IssueWorklogsApi(apiClientPlatform),
new IssueSearchApi(apiClientPlatform),
new IssuesApi(apiClientPlatform)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.rawlabs.protocol.raw.Value;
import org.jetbrains.annotations.Nullable;

import java.time.ZoneId;
import java.util.*;

import static com.rawlabs.das.sdk.java.utils.factory.table.ColumnFactory.createColumn;
Expand All @@ -30,9 +31,10 @@ public class DASJiraBacklogIssueTable extends DASJiraIssueTransformationTable {

private final BoardApi boardApi;

public DASJiraBacklogIssueTable(Map<String, String> options, BoardApi boardApi) {
public DASJiraBacklogIssueTable(Map<String, String> options, ZoneId jiraZoneId, BoardApi boardApi) {
super(
options,
jiraZoneId,
TABLE_NAME,
"The backlog contains incomplete issues that are not assigned to any future or active sprint.");
this.boardApi = boardApi;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.rawlabs.das.jira.rest.platform.ApiException;
import com.rawlabs.das.jira.rest.platform.api.IssueSearchApi;
import com.rawlabs.das.jira.rest.platform.api.IssuesApi;
import com.rawlabs.das.jira.rest.platform.api.MyselfApi;
import com.rawlabs.das.jira.rest.platform.model.IssueBean;
import com.rawlabs.das.jira.rest.platform.model.IssueUpdateDetails;
import com.rawlabs.das.jira.tables.DASJiraIssueTransformationTable;
Expand All @@ -27,15 +26,17 @@ public class DASJiraIssueTable extends DASJiraIssueTransformationTable {
public static final String TABLE_NAME = "jira_issue";
private final IssueSearchApi issueSearchApi;
private final IssuesApi issuesApi;
private final ZoneId zoneId;
private final ZoneId localZoneId;
private final ZoneId jiraZoneId;

public DASJiraIssueTable(
Map<String, String> options, ZoneId zoneId, IssueSearchApi issueSearchApi, IssuesApi issueApi) {
Map<String, String> options, ZoneId jiraZoneId, IssueSearchApi issueSearchApi, IssuesApi issueApi) {
super(
options, TABLE_NAME, "Issues help manage code, estimate workload, and keep track of team.");
options, jiraZoneId, TABLE_NAME, "Issues help manage code, estimate workload, and keep track of team.");
this.issueSearchApi = issueSearchApi;
this.issuesApi = issueApi;
this.zoneId = zoneId;
this.localZoneId = ZoneId.of(options.get("timezone"));
this.jiraZoneId = jiraZoneId;
}

@Override
Expand Down Expand Up @@ -89,7 +90,7 @@ public Row next() {
@Override
public DASJiraPage<IssueBean> fetchPage(long offset) {
try {
String jql = new DASJiraJqlQueryBuilder(zoneId).buildJqlQuery(quals);
String jql = new DASJiraJqlQueryBuilder(localZoneId, jiraZoneId).buildJqlQuery(quals);
var result =
issueSearchApi.searchForIssuesUsingJql(
jql,
Expand Down
Loading

0 comments on commit dc553a4

Please sign in to comment.