2
1
0
2 回答
- 10-1
参考になるかわかりませんが、実際に動くものと組み合わせると下記でできました。
import com.atlassian.jira.component.ComponentAccessor; import com.atlassian.jira.issue.Issue; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.apache.log4j.Level; import org.apache.log4j.Logger; import groovy.json.JsonSlurper; def myLog = Logger.getLogger("com.onresolve.jira.groovy"); myLog.setLevel(Level.DEBUG); String baseUrl = ComponentAccessor.getApplicationProperties().getString("jira.baseurl"); LocalDateTime nowDate = LocalDateTime.now(); DateTimeFormatter dtformat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String dateFrom = "2019-04-01"; String dateTo = dtformat.format(nowDate); Issue issue = (Issue) issue; if (Objects.isNull(issue)) return; String tempoExpenceRestApiUrl = "/rest/tempo-core/1/expense?scopeType=ISSUE&scopeId=" + issue.getId() + "&dateFrom=" + dateFrom + "&dateTo=" + dateTo; String expenseUrl = baseUrl + tempoExpenceRestApiUrl; boolean ConnectionDecisionFlug = false; HttpURLConnection expenseURLConnection = getURLConnection(expenseUrl); ConnectionDecisionFlug = getConnectionDecision(expenseURLConnection); //接続判定 if(!ConnectionDecisionFlug) return; List<Map> expenseJsonParseTextList = getJsonParseTextList(expenseURLConnection); Map<Long, Long> expenseByscopeId_Map = new TreeMap<Long, Long>(); Integer expenseTotal = getExpenseTotal( expenseJsonParseTextList, expenseByscopeId_Map); return expenseTotal; /* ----Function---- */ public HttpURLConnection getURLConnection(String restApiUrl){ try{ URL Url = new URL(restApiUrl); HttpURLConnection UrlConnection = (HttpURLConnection) Url.openConnection(); UrlConnection.setRequestMethod("GET"); UrlConnection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString("userName:password".getBytes())); UrlConnection.setRequestProperty("Content-Type", "application/json"); UrlConnection.setRequestProperty("Accept", "application/json"); return UrlConnection; }catch(IOException e){ e.getMessage(); e.printStackTrace(); } } public getConnectionDecision(HttpURLConnection URLConnection){ try{ if (URLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){ return true; }else{ throw new RuntimeException("Could not establish connection to resource at requested URL."); } } catch (IOException e) { e.getMessage(); e.printStackTrace(); } } public List<Map> getJsonParseTextList(HttpURLConnection URLConnection){ try{ URLConnection.connect(); def jsonParseText = getjsonParseText(URLConnection); if(Objects.nonNull(jsonParseText)) return jsonParseText; } catch (IOException e) { e.getMessage(); e.printStackTrace(); }finally{ URLConnection.disconnect(); } } public List<Map> getjsonParseText(HttpURLConnection URLConnection){ InputStream ips = URLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(isr); try{ String nextLine = br.readLine(); List<Map> jsonParseTextList = (List<Map>) new JsonSlurper().parseText(nextLine); if(Objects.nonNull(nextLine)) return jsonParseTextList; else throw new RuntimeException("The value of nextLine is null.") }catch(IOException e){ e.getMessage(); e.printStackTrace(); }finally{ isr.close(); br.close(); } } public Integer getExpenseTotal( expenseJsonParseTextList, expenseByscopeId_Map){ for (Object expence : expenseJsonParseTextList) { Map expenseMap = (Map) expence; Long scopeId = expenseMap.get('scope').get('scopeId'); Long amount = expenseMap.get('amount'); Long expense = amount; if (expenseByscopeId_Map.containsKey(scopeId)) { expense = expense + expenseByscopeId_Map.get(scopeId); } expenseByscopeId_Map.put(scopeId, expense); log.warn("CHEAK \t" + expense+"\t"+scopeId); } Long expenseTotal = 0; //scopeIdと issue.getId()は同一値 if(expenseByscopeId_Map.containsKey(issue.getId())){ expenseTotal+= expenseByscopeId_Map.get(issue.getId()); } return (Integer)expenseTotal; }
※補足
質問の本質とは関係ないが、JavaScriptでjsonを取り扱う場合var baseUrl = AJS.params.baseURL; var issueKey = JIRA.Issue.getIssueKey(); var jiraWorklogRestApiUrl = "/rest/api/2/issue/" var worklogRestApiUrl = baseUrl + jiraWorklogRestApiUrl + issueKey + "/worklog/"; var rateApiUrl = "https://prudential.rickcloud.jp/jira/rest/tempo-accounts/1/ratetable/" var memberApiUrl = "https://prudential.rickcloud.jp/jira/rest/tempo-teams/2/team/10/member"; var oReq = new XMLHttpRequest(); var oReq1 = new XMLHttpRequest(); var oReq2 = new XMLHttpRequest(); oReq.open("GET", rateApiUrl); oReq.send(); var rateMap = new Map(); var memberMap = new Map(); var roleIdMapByUserName_Map = new Map(); oReq.onreadystatechange = function() { if (oReq.readyState == 4 && oReq.status == 200) { var rateData = JSON.parse(oReq.responseText); rateMap = getRatesMap(rateData); //console.log(rateMap); oReq1.open("GET", memberApiUrl); oReq1.send() } } oReq1.onreadystatechange = function() { if (oReq1.readyState == 4 && oReq1.status == 200) { var memberData = JSON.parse(oReq1.responseText); memberMap = getMemberMap(memberData) roleIdMapByUserName_Map = getRoleIdMapByUserName_Map(rateMap, memberMap); oReq2.open("GET", worklogRestApiUrl); oReq2.send() } } oReq2.onreadystatechange = function() { if (oReq2.readyState == 4 && oReq2.status == 200) { var worklogJsonData = JSON.parse(oReq2.responseText); console.log(worklogJsonData); calculateActualLabor(worklogJsonData.worklogs , rateMap , roleIdMapByUserName_Map); } } function calculateActualLabor(worklogJsonData , rateMap , roleIdMapByUserName_Map){ var total; console.log(worklogJsonData.length); for (var i = 0; i < worklogJsonData.length; i++){ var workerName = worklogJsonData[i].author.name; var timeSpentSeconds = worklogJsonData[i].timeSpentSeconds; var hour = timeSpentSeconds / 3600; var mapIter = roleIdMapByUserName_Map.keys(); if(mapIter.next().value == workerName){ var map = roleIdMapByUserName_Map.get(workerName); var amount = 0; for (let [key, value] of map) { amount = map.get(key) } console.log(amount * hour); } } } function getworklogMap(worklogData){ var workLogJsonData = []; for(var i = 0; i < worklogData.length; i++){ workLogJsonData[i].push(worklogData[i].worklogs); } return workLogJsonData; } function getRoleIdMapByUserName_Map(rateMap, memberMap){ var roleIdMapByUserName_Map = new Map(); for (var [key, value] of memberMap) { var userName = key, roleId = value; var amount = rateMap.get(roleId); var amountByroleId_Map1 = new Map(); amountByroleId_Map1.set(roleId, amount); roleIdMapByUserName_Map.set(userName, amountByroleId_Map1); } return roleIdMapByUserName_Map; } function getMemberMap(data){ var memberMap = new Map(); for(var i = 0, len = data.length; i < len; i++){ var name = data[i].member.name; var roleId = data[i].membership.role.id; //console.log(name + "\t" + roleId); memberMap.set(name, roleId); } return memberMap; } function getRatesMap(data){ var rateMap = new Map() for(var i = 0, len = data.length; i < len; i++){ if(data[i].parent){ var rates = data[i].parent.rates; for(var j = 0; j < rates.length; j++){ var id = 0; if(rates[j].link.id == undefined){ id = rates[j].link.id = -1; }else{ id = rates[j].link.id; } var amount = rates[j].amount; rateMap.set(id,amount) } } } return rateMap; }
コメントを追加... - 321
コメントありがとうございます!参考になります。
RestClientに対してsetProxyで改めてプロキシを設定したところ、想定した動作をすることを確認できました。
JIRAインスタンスの起動オプションに設定するプロキシとは別に、コード上からプロキシを利用して外部APIを呼び出す場合、明示的にしていしてあげなければいけないようです。。
- son
無事動作してよかったです!
そうなのですね。
教えていただきありがとうございます!
コメントを追加...
ScriptRunnerから、外部APIをRESTで呼び出して必要な情報を取得したいと考えています。
以下のようなコードです。
ScriptRunnerのコンソールにて動作を確認したところ、Post function failedとなりました。
JIRAを動かしているTomcatのcatalina.outを確認したところ、以下のようなログが出ているようでした。
処理時間がそんなにかかるとは思えないものの、Tomcatのserver.xmlからValveの時間を120秒から300秒に増やし、JIRAを再起動して再度試したところ、以下のようなエラーが今度はlocalhost.logに出るようになりました。
JIRA ServiceDeskが動作している環境上、プロキシを介さないと外部にアクセスできないため、プロキシが悪さをしているのかとも考えましたが、JIRAの起動プロセスを確認したところ、プロキシは適切に設定されているようでした。JIRAのアドオンなども、ブラウザ上から取得できておりますので、その点は問題ないと考えています。
また、同様のREST EndpointにJIRAが動作している環境(CentOS 7.3)よりcURLでアクセスしたところ、期待した応答が返ってくるため、プロキシに問題があるわけでもなさそうです。
このとき、どのようなケースが考えられるでしょうか。。。
動作環境は、以下の通りです。
JIRA: v8.5.1
JIRA ServiceDesk: 4.5.1(Server版)
ScriptRunner: 5.6.13.1-p5
JIRAが動作している基盤: CentOS Linux release 7.3.1611 (Core)