당연하게도 JIRA Plugin을 개발할 땐 나만의 JQL Function도 만들 수 있다.
"JQL Function이 뭔가요? JQL 그냥 이런거 아닌가요? `issuekey = TEST-1`".
JQL Function은 사용자들이 많이 사용하는 JQL을 아예 함수로 만들어 버린 것들을 말한다. 대표적인 JQL Function은 이런것들이 있다.
- currentUser()
- endOfDay()
- ...
이런게 바로 JQL Function이다. 바로 한번 만들어보자!
참고 자료:
JQL Function 클래스
우선, JQL Function을 만드려면 AbstractJqlFunction이라는 클래스를 상속받아야 한다.
그리고 이 클래스는 다음 5가지를 오버라이딩 해야 한다.
- getFunctionName() : JQL Function 이름을 지정한다.
- validate() : 유효성 검사 메서드.
- getValues() : 실제 JQL Function으로부터 가져올 데이터를 쿼리하는 메서드
- getMinimumNumberOfExpectedArguments() : 최소한으로 필요한 Arguments 개수
- getDataType() : 데이터 타입
KapprovalApprovalFunction
package kr.osci.kapproval.com.jira.jql;
import com.atlassian.jira.JiraDataType;
import com.atlassian.jira.JiraDataTypes;
import com.atlassian.jira.jql.operand.QueryLiteral;
import com.atlassian.jira.jql.query.QueryCreationContext;
import com.atlassian.jira.plugin.jql.function.AbstractJqlFunction;
import com.atlassian.jira.plugin.jql.function.JqlFunction;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.util.MessageSet;
import com.atlassian.query.clause.TerminalClause;
import com.atlassian.query.operand.FunctionOperand;
import kr.osci.kapproval.admin.service.CustomJiraService;
import kr.osci.kapproval.user.service.KapprovalApprovalService;
import lombok.RequiredArgsConstructor;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.stream.Collectors;
@RequiredArgsConstructor
public class KapprovalApprovalFunction extends AbstractJqlFunction implements JqlFunction {
private final KapprovalApprovalService approvalService;
private final CustomJiraService jiraService;
@Nonnull
@Override
public String getFunctionName() {
return "kapprovalApproval";
}
@Nonnull
@Override
public MessageSet validate(ApplicationUser applicationUser,
@Nonnull FunctionOperand functionOperand,
@Nonnull TerminalClause terminalClause) {
return validateNumberOfArgs(functionOperand, 0);
}
/**
* 이슈들을 쿼리하는 메서드
* @param queryCreationContext
* @param functionOperand
* @param terminalClause
* @return
*/
@Nonnull
@Override
public List<QueryLiteral> getValues(@Nonnull QueryCreationContext queryCreationContext,
@Nonnull FunctionOperand functionOperand,
@Nonnull TerminalClause terminalClause) {
return approvalService
.getApprovalIssueKeyByApproverId(queryCreationContext.getApplicationUser().getId())
.stream()
.map(issueId -> new QueryLiteral(functionOperand, jiraService.getIssueKey(issueId)))
.collect(Collectors.toList());
}
@Override
public int getMinimumNumberOfExpectedArguments() {
return 0;
}
@Nonnull
@Override
public JiraDataType getDataType() {
return JiraDataTypes.ISSUE;
}
}
위 코드를 보자. 가장 중요한 건 당연하겠지만 데이터를 쿼리하는 메서드인 getValues()이다. 비즈니스 로직에 따라 이 메서드 안에서 내가 이 JQL Function이 어떤 이슈들을 보여줄건지 정해야 한다. 그리고 반환 타입은 List<QueryLiteral>이다.
QueryLiteral의 첫번째 인자는 파라미터로 받는 FunctionOperand 객체를 넘겨주면 된다. 두번째 객체는 String 타입 또는 Long 타입의 가져올 데이터의 값이다. 만약 getDataType()이 반환하는 값이 JiraDataTypes.ISSUE로 되어 있다면 이슈의 키를 반환하면 된다.
그래서 위 코드를 보면 결국 반환은 가져온 모든 QueryLiteral 객체 데이터를 리스트로 넘긴다.
이 메서드의 내부 로직은 본인이 원하는 이슈들을 가져오게끔 작성하면 된다. 예를 들어, 이슈의 상태가 `Closed` 상태인 모든 이슈라던가, Assignee가 `XXX`인 사람의 모든 이슈 등 원하는 이슈 쿼리를 하면 된다.
JQL Function 리소스 등록
이제 익숙해질때도 됐다. 플러그인의 모든 리소스는 다 Add-on Descriptor(atlassian-plugin.xml)에 등록해야 한다.
그래서 다음과 같이 등록해보자.
<jql-function name="K-Approval Approval" i18n-name-key="jql.approval" key="jqlKapprovalApproval" class="kr.osci.kapproval.com.jira.jql.KapprovalApprovalFunction">
<fname>Approval</fname>
<description key="KapprovalApprovalDescription">Approval function</description>
<list>true</list>
</jql-function>
이 jql-function 태그의 class attribute를 보자. 이 attribute에 방금 위에서 만든 클래스의 타입(패키지 + 클래스)을 적어주면 된다.
이 부분이 제일 중요하고 나머지는 메타데이터에 가깝다.
fname 태그는 그냥 Function 이름이라고 생각하면 된다. 그리고 list 태그는 이 JQL Function의 결과가 단일 이슈인지 리스트인지를 알려준다. 이렇게 등록을 하면 끝난다. 실제로 이 JQL Function이 잘 보일것이다.
'Jira & ScriptRunner' 카테고리의 다른 글
Jira DC 플러그인 개발 Part.8 이벤트 리스너 등록하기 (0) | 2024.07.23 |
---|---|
Jira DC 플러그인 개발 Part.7 서블릿 필터 만들기 (Java에서 하던것과 똑같다) (0) | 2024.07.23 |
Jira DC 플러그인 개발 Part.5 - 상단 네비게이션 바에 앱 링크 노출하기 (0) | 2024.07.16 |
Jira DC 플러그인 개발 Part.4 - ActiveObjects ORM (0) | 2024.07.15 |
Jira DC 플러그인 개발 Part.3 관리자 화면 메뉴 섹션 (0) | 2024.07.15 |