Skip to content

Commit

Permalink
Reformat code with spotless
Browse files Browse the repository at this point in the history
  • Loading branch information
marko-bekhta committed Oct 8, 2024
1 parent 5dcac68 commit 55674e3
Show file tree
Hide file tree
Showing 42 changed files with 949 additions and 951 deletions.
31 changes: 20 additions & 11 deletions src/main/java/org/hibernate/infra/sync/jira/JiraConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,43 +79,52 @@ interface ValueMapping {

interface IssueLinkTypeValueMapping extends ValueMapping {
/**
* @return the value of the issue link type id to use for linking a "sub-task" ticket to a "parent"
* NOTE: Since changing issue to a subtask doesn't work through the REST API we are creating a regular
* task instead and adding an extra link for it.
* @return the value of the issue link type id to use for linking a "sub-task"
* ticket to a "parent" NOTE: Since changing issue to a subtask doesn't
* work through the REST API we are creating a regular task instead and
* adding an extra link for it.
*/
String parentLinkType();
}

interface UserValueMapping extends ValueMapping {
/**
* @return the name of the property to apply the assignee value to.
* With Jira Server the required property is {@code name}, while for the Cloud an {@code accountId} is expected.
* @return the name of the property to apply the assignee value to. With Jira
* Server the required property is {@code name}, while for the Cloud an
* {@code accountId} is expected.
*/
@WithDefault("accountId")
String mappedPropertyName();
}

/**
* Some JIRA instances may allow PAT logins (personal authentication tokens) while others: basic authentication with a username password/token
* Some JIRA instances may allow PAT logins (personal authentication tokens)
* while others: basic authentication with a username password/token
*/
enum LoginKind {
/**
* Basic authentication with a username password/token. A string {@code username:password} is {@code base64}-encoded and passed in the auth header.
* Basic authentication with a username password/token. A string
* {@code username:password} is {@code base64}-encoded and passed in the auth
* header.
*/
BASIC {
@Override
public Map<String, String> headers(String username, String token) {
return Map.of( "Authorization", "Basic %s".formatted( Base64.getEncoder().encodeToString( ( "%s:%s".formatted( username, token ) ).getBytes() ) ) );
return Map.of("Authorization", "Basic %s".formatted(
Base64.getEncoder().encodeToString(("%s:%s".formatted(username, token)).getBytes())));
}
},
/**
* A PAT login, where a JIRA generated token is simply passed as is in the header without any additional encoding, usernames or anything else.
* See also <a href="https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html">personal access tokens</a>
* A PAT login, where a JIRA generated token is simply passed as is in the
* header without any additional encoding, usernames or anything else. See also
* <a href=
* "https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html">personal
* access tokens</a>
*/
BEARER_TOKEN {
@Override
public Map<String, String> headers(String username, String token) {
return Map.of( "Authorization", "Bearer %s".formatted( token ) );
return Map.of("Authorization", "Bearer %s".formatted(token));
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import org.eclipse.microprofile.health.Startup;

/**
* Since we do not depend on any resources let's just have this simplest check to see if the app is running.
* Since we do not depend on any resources let's just have this simplest check
* to see if the app is running.
*/
@Startup
@Readiness
Expand All @@ -17,10 +18,8 @@ public class IsAppRunningCheck implements HealthCheck {

@Override
public HealthCheckResponse call() {
return HealthCheckResponse.builder()
.name( NAME )
.withData( "details", "The app is up and running, and should be able to accept webhook POSTs." )
.up()
return HealthCheckResponse.builder().name(NAME)
.withData("details", "The app is up and running, and should be able to accept webhook POSTs.").up()
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.hibernate.infra.sync.jira.service.jira.JiraService;
import org.hibernate.infra.sync.jira.service.jira.model.hook.JiraWebHookEvent;
import org.hibernate.infra.sync.jira.service.validation.ConfiguredProject;

import org.jboss.resteasy.reactive.RestPath;

Expand All @@ -23,9 +22,10 @@ public class JiraWebHookListenerResource {
@POST
@Path("/{project}")
@Consumes(MediaType.APPLICATION_JSON)
public String somethingHappened(@RestPath @NotNull /* @ConfiguredProject */ String project, JiraWebHookEvent event) {
Log.debugf( "Received a notification about %s project: %s", project, event );
jiraService.acknowledge( project, event );
public String somethingHappened(@RestPath @NotNull /* @ConfiguredProject */ String project,
JiraWebHookEvent event) {
Log.debugf("Received a notification about %s project: %s", project, event);
jiraService.acknowledge(project, event);
return "ack";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

public final class HandlerProjectContext {

// JIRA REST API creates upto 50 issues at a time: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-bulk-post
// JIRA REST API creates upto 50 issues at a time:
// https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-bulk-post
private static final int ISSUES_PER_REQUEST = 25;
private static final String SYNC_ISSUE_PLACEHOLDER_SUMMARY = "Sync issue placeholder";
private final ReentrantLock lock = new ReentrantLock();
Expand All @@ -28,17 +29,16 @@ public final class HandlerProjectContext {
private final AtomicLong currentIssueKeyNumber;
private final JiraIssueBulk bulk;

public HandlerProjectContext(
String projectName, String projectGroupName, JiraRestClient sourceJiraClient, JiraRestClient destinationJiraClient, JiraConfig.JiraProjectGroup projectGroup
) {
public HandlerProjectContext(String projectName, String projectGroupName, JiraRestClient sourceJiraClient,
JiraRestClient destinationJiraClient, JiraConfig.JiraProjectGroup projectGroup) {
this.projectName = projectName;
this.projectGroupName = projectGroupName;
this.sourceJiraClient = sourceJiraClient;
this.destinationJiraClient = destinationJiraClient;
this.projectGroup = projectGroup;
this.project = projectGroup().projects().get( projectName() );
this.currentIssueKeyNumber = new AtomicLong( getCurrentLatestJiraIssueKeyNumber() );
this.bulk = new JiraIssueBulk( createIssuePlaceholder(), ISSUES_PER_REQUEST );
this.project = projectGroup().projects().get(projectName());
this.currentIssueKeyNumber = new AtomicLong(getCurrentLatestJiraIssueKeyNumber());
this.bulk = new JiraIssueBulk(createIssuePlaceholder(), ISSUES_PER_REQUEST);
}

public JiraConfig.JiraProject project() {
Expand Down Expand Up @@ -70,60 +70,58 @@ public AtomicLong currentIssueKeyNumber() {
}

public Long getLargestSyncedJiraIssueKeyNumber() {
JiraIssues issues = destinationJiraClient.find( "project = %s and summary !~\"%s\" ORDER BY key DESC".formatted( project.projectId(), SYNC_ISSUE_PLACEHOLDER_SUMMARY ), 0, 1 );
if ( issues.issues.isEmpty() ) {
JiraIssues issues = destinationJiraClient.find("project = %s and summary !~\"%s\" ORDER BY key DESC"
.formatted(project.projectId(), SYNC_ISSUE_PLACEHOLDER_SUMMARY), 0, 1);
if (issues.issues.isEmpty()) {
return 0L;
}
else {
return JiraIssue.keyToLong( issues.issues.get( 0 ).key );
} else {
return JiraIssue.keyToLong(issues.issues.get(0).key);
}
}

public Optional<JiraIssue> getNextIssueToSync(Long latestSyncedJiraIssueKeyNumber) {
JiraIssues issues = destinationJiraClient.find( "project = %s and key > %s-%s ORDER BY key ASC"
.formatted( project.originalProjectKey(), project.originalProjectKey(), latestSyncedJiraIssueKeyNumber ), 0, 1 );
if ( issues.issues.isEmpty() ) {
JiraIssues issues = destinationJiraClient.find("project = %s and key > %s-%s ORDER BY key ASC".formatted(
project.originalProjectKey(), project.originalProjectKey(), latestSyncedJiraIssueKeyNumber), 0, 1);
if (issues.issues.isEmpty()) {
return Optional.empty();
}
else {
return Optional.of( issues.issues.get( 0 ) );
} else {
return Optional.of(issues.issues.get(0));
}
}

private Long getCurrentLatestJiraIssueKeyNumber() {
try {
JiraIssues issues = destinationJiraClient.find( "project = %s ORDER BY created DESC".formatted( project.projectId() ), 0, 1 );
if ( issues.issues.isEmpty() ) {
JiraIssues issues = destinationJiraClient
.find("project = %s ORDER BY created DESC".formatted(project.projectId()), 0, 1);
if (issues.issues.isEmpty()) {
return 0L;
} else {
return JiraIssue.keyToLong(issues.issues.get(0).key);
}
else {
return JiraIssue.keyToLong( issues.issues.get( 0 ).key );
}
}
catch (Exception e) {
} catch (Exception e) {
return -1L;
}
}

public void createNextPlaceholderBatch(String upToKey) {
createNextPlaceholderBatch( JiraIssue.keyToLong( upToKey ) );
createNextPlaceholderBatch(JiraIssue.keyToLong(upToKey));
}

public void createNextPlaceholderBatch(Long upToKeyNumber) {
if ( requiredIssueKeyNumberShouldBeAvailable( upToKeyNumber ) ) {
if (requiredIssueKeyNumberShouldBeAvailable(upToKeyNumber)) {
return;
}
lock.lock();
if ( requiredIssueKeyNumberShouldBeAvailable( upToKeyNumber ) ) {
if (requiredIssueKeyNumberShouldBeAvailable(upToKeyNumber)) {
return;
}
try {
do {
JiraIssueBulkResponse response = destinationJiraClient.create( bulk );
response.issues.stream().mapToLong( i -> JiraIssue.keyToLong( i.key ) ).max().ifPresent( currentIssueKeyNumber::set );
} while ( currentIssueKeyNumber.get() < upToKeyNumber );
}
finally {
JiraIssueBulkResponse response = destinationJiraClient.create(bulk);
response.issues.stream().mapToLong(i -> JiraIssue.keyToLong(i.key)).max()
.ifPresent(currentIssueKeyNumber::set);
} while (currentIssueKeyNumber.get() < upToKeyNumber);
} finally {
lock.unlock();
}
}
Expand All @@ -143,7 +141,7 @@ private JiraIssue createIssuePlaceholder() {
placeholder.fields.issuetype.id = projectGroup().issueTypes().defaultValue();

// just to be sure that these are not sent as part of
// the placeholder request to keep it as simple as it can be:
// the placeholder request to keep it as simple as it can be:
placeholder.fields.reporter = null;
placeholder.fields.assignee = null;
placeholder.fields.priority = null;
Expand All @@ -153,7 +151,10 @@ private JiraIssue createIssuePlaceholder() {

@Override
public String toString() {
return "HandlerProjectContext[" + "projectName=" + projectName + ", " + "projectGroupName=" + projectGroupName + ", " + "sourceJiraClient=" + sourceJiraClient + ", " + "destinationJiraClient=" + destinationJiraClient + ", " + "projectGroup=" + projectGroup + ", " + "currentIssueKeyNumber=" + currentIssueKeyNumber + ']';
return "HandlerProjectContext[" + "projectName=" + projectName + ", " + "projectGroupName=" + projectGroupName
+ ", " + "sourceJiraClient=" + sourceJiraClient + ", " + "destinationJiraClient="
+ destinationJiraClient + ", " + "projectGroup=" + projectGroup + ", " + "currentIssueKeyNumber="
+ currentIssueKeyNumber + ']';
}

}
Loading

0 comments on commit 55674e3

Please sign in to comment.