Index: aRMS_README.md =================================================================== diff -u -r9328381608b679a7f66c02117a302fc4fa22d1a5 -re3ecbaaac8d23fc3a967b138af1b4c42956a87b4 --- aRMS_README.md (.../aRMS_README.md) (revision 9328381608b679a7f66c02117a302fc4fa22d1a5) +++ aRMS_README.md (.../aRMS_README.md) (revision e3ecbaaac8d23fc3a967b138af1b4c42956a87b4) @@ -4,4 +4,66 @@ 패키지명은 무조건 소문자 통일 클래스명은 카멜 케이스 통일 -sqlmapper 셀렉터의 sqlmap 네임스페이스는 무조건 소문자 ( 패키지 명에 해당 ) \ No newline at end of file +sqlmapper 셀렉터의 sqlmap 네임스페이스는 무조건 소문자 ( 패키지 명에 해당 ) + +기업의 부채율은 부담을 가중 시킬 것이고, +효율 경영을 위한 활동을 할 것이다. ( 컨설팅 등 ) +암암리에 진행하는 구조조정이 있을 것이고, +표면적인 정량적 평가에 의한 구분이 병행하고 싶을 것이다. +그 데이터 확보에 어려움을 겪을 것이고 +여기에 a-RMS는 그 답을 제시해 줄 것이다. +기회다. 왜냐하면 a-RMS는 프로세스를 변화시키는 욕구를 충족시킬 것이고, +정량적 평가와 함께 회사에 유리한 지표를 제공할 테니까. + +a-RMS 의 JIRA Issue Type 에 관하여 +1. 지라 이슈 타입 ( 요구사항 이슈 타입이 없으니까 ) + 만들어야 할 경우 지라 버전이 Major 7 이상이어야 한다. + +2. 지라 5,6 버전은 메뉴얼 문서를 주고 admin 이 직접 요구사항 이슈 타입을 + 만들게 유도하고, a-RMS에서 이슈타입을 써치하는 ( 조회하는 ) 방식으로 구현 + +3. 이것도 싫은 경우가 발생할 수 있는데, + 5,6 버전이라면 아마 내부적으로도 오래동안 쓴 케이스 일 것이므로, + 보수적일 가능성이 있다. 공식 a-RMS 플러그인을 만들어서 + 이슈 타입을 생성해 주는 방식을 고려 해야 할 것이다 ( 우선순위 낮음 ) + +[ 레퍼런스 문서 ] +https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-types/#api-rest-api-3-issuetype-id-get +https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-types/#api-rest-api-2-issuetype-post +https://docs.atlassian.com/software/jira/docs/api/REST/8.1.0/#api/2/issuetype-createIssueType +https://docs.atlassian.com/software/jira/docs/api/REST/5.2.11/#api/2/issuetype-createIssueType +[ a-RMS의 JIRA 전체 흐름 ] +1. 사용자가 a-RMS에 제품(서비스)를 만들고 +2. 해당 제품의 버전을 구성하면 -> JIRA에 반영을 해야 한다. +3. 아직은 JIRA 연결이 되어 있지 않기 때문에 대기 상태일거고 +4. 제품(서비스) - 버전 - JIRA 연결을 생성하면, +5. 해당 JIRA 프로젝트에 Version 을 생성해 준다. ( 예 : 제품(서비스)-Version ) +6. 5번 과정이 끝나면 바로 요구사항 이슈 타입이 존재하는지 확인하고 +7. 사용자에게 지라 버전이 5,6 이라면 admin 에게 요구 사항 이슈 타입을 생성해 달라고 요청을 유도한다. +8. 요구사항이 구성되기 시작하면, 요구사항 이슈 타입으로 설정된 프로젝트에 이슈를 생성한다. +9. 생성 후 이슈 링크를 확인하고 스크랩을 해 온다. +10. 지라 프로젝트 생성은 지원하지 않는다. +11. 이미 있는 프로젝트에 연결을 지원한다. ( a-RMS 백오피스에서 지원을 하는건 고려 중 ) + +12. 이후 주기적인 요구사항 이슈를 수집하여 ELK 에 적재한다. + +따라서 다음과 같은 테스트 케이스가 선행되어야 한다. + +[ 테스트 케이스 ] +1. Jira Project 를 로드하여 a-RMS에 적재 할 수 있어야 한다. +2. 적재된 a-RMS Jira Project는 a-RMS Jira 연결 관리에서 볼 수 있어야 한다. +3. a-RMS 의 제품(서비스) - 버전 - JIra 연결 구성이 이루어 지면 +4. 해당하는 Jira Project 에 "aRMS-제품(서비스)-Version" 이 존재하는지 확인한다. +5. 없으면 생성한다. +6. 해당 Jira Project 에 요구사항 이슈 타입을 쓸 수 있는 버전인지 확인한다. +7. 7 이상의 버전이면, 요구사항 이슈 타입이 없으면 생성해 준다. +8. 5,6 버전이면, 알림 창을 띄워서 admin 이 요구사항 이슈 타입을 생성하도록 유도 +9. a-RMS에 요구사항이 등록되고 , 리뷰어가 리뷰를 완료하면, +10. 주기적으로 요구사항을 확인하여, Jira 에 이슈를 생성한다. ( 요구사항 타입 ) +11. 이후 스케쥴러를 동작해서 요구사항 이슈를 수집하여 ELK 에 적재한다. ( 릴레이션, Sub-TASK 포함 ) +히스토리와 기타 등등 모든 수집 대상을 ELK 에 비정형으로 적재한다. + +[ 이슈 타입에 대한 로직 ] +1. 지라 글로벌 이슈 타입을 써치 할 수 있다. +2. 지라 글로벌 요구사항 타입을 생성할 수 있다. +3. 이슈 스키마에 요구사항 타입을 맵핑 할 수 있다. Index: pom.xml =================================================================== diff -u -r5fb5e212ad72e8ff4a11804b60b1831ac8410442 -re3ecbaaac8d23fc3a967b138af1b4c42956a87b4 --- pom.xml (.../pom.xml) (revision 5fb5e212ad72e8ff4a11804b60b1831ac8410442) +++ pom.xml (.../pom.xml) (revision e3ecbaaac8d23fc3a967b138af1b4c42956a87b4) @@ -10,7 +10,7 @@ 4.0.0 313devgrp java-service-tree-framework-backend-server - 22.11.30 + 22.12.01 pom java-service-tree-framework Index: web-module/pom.xml =================================================================== diff -u -r5fb5e212ad72e8ff4a11804b60b1831ac8410442 -re3ecbaaac8d23fc3a967b138af1b4c42956a87b4 --- web-module/pom.xml (.../pom.xml) (revision 5fb5e212ad72e8ff4a11804b60b1831ac8410442) +++ web-module/pom.xml (.../pom.xml) (revision e3ecbaaac8d23fc3a967b138af1b4c42956a87b4) @@ -7,7 +7,7 @@ 313devgrp java-service-tree-framework-backend-server - 22.11.30 + 22.12.01 ../pom.xml @@ -19,9 +19,9 @@ 23.01.12 - + 313devgrp @@ -97,14 +97,14 @@ 2.0.0-m15 - com.mashape.unirest - unirest-java - 1.4.9 + org.apache.httpcomponents + httpclient + 4.2.1-atlassian-2 org.apache.httpcomponents - httpcore-nio - 4.4.3 + httpasyncclient + 4.0-beta3-atlassian-1 Index: web-module/src/test/java/egovframework/api/arms/module_pdservicejira/ArmsJiraClientTest.java =================================================================== diff -u -r5fb5e212ad72e8ff4a11804b60b1831ac8410442 -re3ecbaaac8d23fc3a967b138af1b4c42956a87b4 --- web-module/src/test/java/egovframework/api/arms/module_pdservicejira/ArmsJiraClientTest.java (.../ArmsJiraClientTest.java) (revision 5fb5e212ad72e8ff4a11804b60b1831ac8410442) +++ web-module/src/test/java/egovframework/api/arms/module_pdservicejira/ArmsJiraClientTest.java (.../ArmsJiraClientTest.java) (revision e3ecbaaac8d23fc3a967b138af1b4c42956a87b4) @@ -1,35 +1,34 @@ package egovframework.api.arms.module_pdservicejira; +import com.atlassian.jira.rest.client.api.GetCreateIssueMetadataOptions; import com.atlassian.jira.rest.client.api.JiraRestClient; -import com.atlassian.jira.rest.client.api.domain.Issue; -import com.atlassian.jira.rest.client.api.domain.IssueType; +import com.atlassian.jira.rest.client.api.domain.*; +import com.atlassian.jira.rest.client.api.domain.input.VersionInput; import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory; import com.atlassian.util.concurrent.Promise; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.mashape.unirest.http.HttpResponse; -import com.mashape.unirest.http.JsonNode; -import com.mashape.unirest.http.ObjectMapper; -import com.mashape.unirest.http.Unirest; -import com.mashape.unirest.http.exceptions.UnirestException; +import org.joda.time.DateTime; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Iterator; public class ArmsJiraClientTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Test - public void jiraTest() throws URISyntaxException, IOException { + public JiraRestClient getJiraRestClient() throws URISyntaxException { final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory(); URI jiraServerUri = new URI("http://www.313.co.kr/jira"); - final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(jiraServerUri, "admin", "####"); + return factory.createWithBasicHttpAuthentication(jiraServerUri, "admin", "flexjava"); + } + + @Test + public void jiraTest() throws URISyntaxException, IOException { + final JiraRestClient restClient = getJiraRestClient(); try { Promise> test = restClient.getMetadataClient().getIssueTypes(); @@ -47,56 +46,116 @@ } } + + //a-RMS :: Jira Project 를 로드하여 a-RMS에 적재 할 수 있어야 한다. @Test - public void create_IssueType() throws UnirestException { - // The payload definition using the Jackson library + public void getAll_JiraProject() throws URISyntaxException { + final JiraRestClient restClient = getJiraRestClient(); + Promise> promise = restClient.getProjectClient().getAllProjects(); + Iterable allProject = promise.claim(); + for (BasicProject project: allProject) { + logger.info("project -> " + project.getName()); + logger.info("project -> " + project.getKey()); + logger.info("project -> " + project.getSelf()); + } - JsonNodeFactory jnf = JsonNodeFactory.instance; - ObjectNode payload = jnf.objectNode(); - { - payload.put("name", "requirement"); - payload.put("description", "arms"); - payload.put("type", "standard"); - payload.put("atl_token", "BU13-CS25-DME9-DDDH|3a94d109d3f161e1c8741267e03261ad3a0e9263|lin"); + } + + @Test + public void getSingle_JiraProject() throws URISyntaxException { + final JiraRestClient restClient = getJiraRestClient(); + String jira_Project_KEY = "SP"; + Promise promise = restClient.getProjectClient().getProject(jira_Project_KEY); + Project project = promise.claim(); + logger.info("getSingle_JiraProject => " + project.getDescription()); + logger.info("getSingle_JiraProject => " + project.getKey()); + logger.info("getSingle_JiraProject => " + project.getName()); + + logger.info("getSingle_JiraProject => " + project.getComponents()); + logger.info("getSingle_JiraProject => " + project.getIssueTypes()); + logger.info("getSingle_JiraProject => " + project.getLead()); + + logger.info("getSingle_JiraProject => " + project.getProjectRoles()); + logger.info("getSingle_JiraProject => " + project.getUri()); + logger.info("getSingle_JiraProject => " + project.getVersions()); + } + + //a-RMS :: 해당하는 Jira Project 에 "aRMS-제품(서비스)-Version" 이 존재하는지 확인한다. + //a-RMS :: 없으면 생성한다. + @Test + public void set_JiraVersion_ToProject() throws URISyntaxException { + final JiraRestClient restClient = getJiraRestClient(); + String projectKey = "JSTFFW"; + String name = "a-RMS 제품(서비스) 버전"; + String description = "a-RMS Desc"; + DateTime releaseDate = new DateTime("2022-12-31"); + boolean isArchived = false; + boolean isReleased = false; + VersionInput createVersionTest = new VersionInput(projectKey, name, description, releaseDate, isArchived, isReleased); + Promise test = restClient.getVersionRestClient().createVersion(createVersionTest); + Version version = test.claim(); + logger.info("version getName = " + version.getName()); + logger.info("version getDescription = " + version.getDescription()); + logger.info("version getId = " + version.getId()); + logger.info("version getReleaseDate = " + version.getReleaseDate()); + logger.info("version getSelf = " + version.getSelf()); + } + + //a-RMS :: 해당 Jira Project 에 요구사항 이슈 타입을 쓸 수 있는 버전인지 확인한다. + @Test + public void get_Jira_InstalledVersion() throws URISyntaxException { + final JiraRestClient restClient = getJiraRestClient(); + ServerInfo serverInfo = restClient.getMetadataClient().getServerInfo().claim(); + logger.info("serverInfo = " + serverInfo.getScmInfo()); + logger.info("serverInfo = " + serverInfo.getServerTitle()); + logger.info("serverInfo = " + serverInfo.getVersion()); + logger.info("serverInfo = " + serverInfo.getBaseUri()); + logger.info("serverInfo = " + serverInfo.getBuildDate()); + logger.info("serverInfo = " + serverInfo.getBuildNumber()); + logger.info("serverInfo = " + serverInfo.getBaseUri()); + } + + //a-RMS :: 7 이상의 버전이면, 요구사항 이슈 타입이 없으면 생성해 준다. + //a-RMS :: 5,6 버전이면, 알림 창을 띄워서 admin 이 요구사항 이슈 타입을 생성하도록 유도 + //@Test + public void set_Requirement_IssueType() throws URISyntaxException { + // 추후 개발 + } + + @Test + public void getAll_IssueType() throws URISyntaxException { + final JiraRestClient restClient = getJiraRestClient(); + Promise> promise = restClient.getMetadataClient().getIssueTypes(); + Iterable issueTypes = promise.claim(); + for (IssueType issueType: issueTypes) { + logger.info("issueType => " + issueType.getId()); + logger.info("issueType => " + issueType.getName()); + logger.info("issueType => " + issueType.getSelf()); + logger.info("issueType => " + issueType.getDescription()); + logger.info("issueType => " + issueType.getIconUri()); } + } - // Connect Jackson ObjectMapper to Unirest + public void getSingle_IssueType() { - Unirest.setObjectMapper(new ObjectMapper() { - private com.fasterxml.jackson.databind.ObjectMapper jacksonObjectMapper - = new com.fasterxml.jackson.databind.ObjectMapper(); + } - public T readValue(String value, Class valueType) { - try { - return jacksonObjectMapper.readValue(value, valueType); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + //이슈 타입은 7 버전 이상에서만 지원. + //@Test - public String writeValue(Object value) { - try { - logger.info("value =" + value); - logger.info("jacksonObjectMapper.writeValueAsString(value) = " + jacksonObjectMapper.writeValueAsString(value)); - return jacksonObjectMapper.writeValueAsString(value); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - }); + //a-RMS :: Jira 에 이슈를 생성한다. ( 요구사항 타입 ) + public void set_RequirementIssue_aRMS() { -// This code sample uses the 'Unirest' library: -// http://unirest.io/java.html - HttpResponse response = Unirest - .post("http://www.313.co.kr/jira/rest/api/2/issuetype") - .basicAuth("admin", "####") - .header("Accept", "application/json") - .header("Content-Type", "application/json") - .body(payload) - .asJson(); + } - logger.info(response.toString()); - System.out.println(response.getBody()); + //a-RMS :: 등록된 요구사항 이슈를 수집 할 수 있다. + //a-RMS :: 주기적으로 요구사항을 확인하여, Jira 에 이슈를 생성한다. ( 요구사항 타입 )( 릴레이션, Sub-TASK 포함 ) + public void get_RequirementIssue_aRMS() { + } + //a-RMS :: 이후 스케쥴러를 동작해서 요구사항 이슈를 수집하여 ELK 에 적재한다. + public void store_ReqIssue_ToELK_ByaRMS() { + + } } Index: web-module/src/test/java/egovframework/com/ext/jstree/support/util/Java8LambdaTest.java =================================================================== diff -u -rd774ff7bf7165a72f9807914bf1c0e97e93b26ac -re3ecbaaac8d23fc3a967b138af1b4c42956a87b4 --- web-module/src/test/java/egovframework/com/ext/jstree/support/util/Java8LambdaTest.java (.../Java8LambdaTest.java) (revision d774ff7bf7165a72f9807914bf1c0e97e93b26ac) +++ web-module/src/test/java/egovframework/com/ext/jstree/support/util/Java8LambdaTest.java (.../Java8LambdaTest.java) (revision e3ecbaaac8d23fc3a967b138af1b4c42956a87b4) @@ -2,7 +2,6 @@ import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.HttpClientBuilder; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -331,35 +330,35 @@ //@Test public void putJsonObjectFromInfluxDBapiTest() throws ParseException { - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); - factory.setReadTimeout(5000); // 읽기시간초과, ms - factory.setConnectTimeout(3000); // 연결시간초과, ms - HttpClient httpClient = HttpClientBuilder.create() - .setMaxConnTotal(100) // connection pool 적용 - .setMaxConnPerRoute(5) // connection pool 적용 - .build(); - factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅 +// HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); +// factory.setReadTimeout(5000); // 읽기시간초과, ms +// factory.setConnectTimeout(3000); // 연결시간초과, ms +// HttpClient httpClient = HttpClientBuilder.create() +// .setMaxConnTotal(100) // connection pool 적용 +// .setMaxConnPerRoute(5) // connection pool 적용 +// .build(); +// factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅 +// +// RestTemplate restTemplate = new RestTemplate(factory); +// +// HttpHeaders headers = createHttpHeaders("admin","qwe123"); +// headers.setContentType(MediaType.APPLICATION_JSON); +// +// String postdata = "{\n" + +// " \"name\":\"test_datasource\",\n" + +// " \"type\":\"influxdb\",\n" + +// " \"url\":\"http://influxdb:8086313\",\n" + +// " \"access\":\"proxy\",\n" + +// " \"basicAuth\":false\n" + +// "}"; +// +// HttpEntity request = new HttpEntity(postdata, headers); +// +// String influxdbBaseUrl = "http://192.168.25.46:3000/api/datasources"; +// String returnResultStr = restTemplate.postForObject( influxdbBaseUrl, request, String.class); +// +// logger.info(returnResultStr); - RestTemplate restTemplate = new RestTemplate(factory); - - HttpHeaders headers = createHttpHeaders("admin","qwe123"); - headers.setContentType(MediaType.APPLICATION_JSON); - - String postdata = "{\n" + - " \"name\":\"test_datasource\",\n" + - " \"type\":\"influxdb\",\n" + - " \"url\":\"http://influxdb:8086313\",\n" + - " \"access\":\"proxy\",\n" + - " \"basicAuth\":false\n" + - "}"; - - HttpEntity request = new HttpEntity(postdata, headers); - - String influxdbBaseUrl = "http://192.168.25.46:3000/api/datasources"; - String returnResultStr = restTemplate.postForObject( influxdbBaseUrl, request, String.class); - - logger.info(returnResultStr); - } //@Test