Lotus и Jira

Omh

Well-Known Member
Lotus team
04.07.2007
2 210
1
#1
Камрады программисты, кто-нибудь делал интеграцию Atlassian Jira и нашего любимого LN?
В данный момент мне хватит того, что по issue ID получить описание (для начала).

Нашёл описание Jira API: http://docs.atlassian.com/software/jira/do...ew-summary.html
Не понимаю, с какой стороны подступится.

Можеть кто-то подкинет вектор движения.
Спасибо.
 

Gor

Well-Known Member
07.06.2005
517
2
#2
Добрый день всем!

Вопрос тот же, - был ли у кого опыт интеграции Lotus - Jira??
Интересует автоматическое открытие кейсов в Jira из Лотусового интерфейса... и впоследствии двусторонее общение (в Jira исполнение задач - Лотус как дисплей выполнения)

Может кто нибудь поделится опытом, куда копать, с чего начать, как подружить сие продукты.
Если у кого нибудь есть какие либо наработки по этому поводу - буду очень благодарен!!
 
13.03.2009
625
2
#3
Есть eclipse плагин mylyn, который кроме прочего умеет интегрироваца с jira. Теоретически - должен встать и на dde. Может в этом направлении поковырять?
Subversion я прикручивал ( только толку от него почти нет )
 

Gor

Well-Known Member
07.06.2005
517
2
#4
мдя, не густо...
Неужели старые добрые дедушкины перекладчики использовать придётся и разбор файлов (со стороны Jira писать сервисы, со стороны лотуса агенты) =((((

to Omh
Значит по этой теме у вас продвижек так и не было?
 

Gor

Well-Known Member
07.06.2005
517
2
#5
Если кому либо будет интересна данная тема кое что начинает срастаться.

В Jira есть RPC плагин, который если включить генерит тебе wsdl-ку, которая позволяет общаться Jira с другими приложениями через Web сервисы.

Как включить данный плагин в Jira - http://confluence.atlassian.com/display/JI...g+a+SOAP+Client

Там же по ссылке есть пример кода на Java и на Python, который возволяет создать программно Issue в каком нибудь Проекте, позволяет прочитать что либо, создать итд итп

================================================================================
=========

Так как Jav-ой к сожалению не владею, а задача как всегда должна быть выполнена "вчера" пошёл методом создания WEb Service COnsumer на LS с использванием SOAP Toolkit 3.0.

обращаюсь к данной wsdl-ке на лотус скриптах, методы getIssue, итд итп проходят, возвращают необходимую информацию по ID, а вот с методом CreateIssue беда...

судя по web сервису, есть такой метод CreateIssue, у него на входе два параметра.

судя по примерам (http://confluence.atlassian.com/display/JIRA/Creating+a+SOAP+Client)
на языке Python к нему обращаются следующим образом:

<!--shcode--><pre><code class='ls'>newissue = soap.createIssue(auth, {'project': 'TST', 'type': '1', 'summary': 'Issue created with Python!'})[/CODE]
т.е. первый параметр - auth, второй {'project': 'TST', 'type': '1', 'summary': 'Issue created with Python!'}

С первым параметром всё понятно, он стринговый,
но не пойму как второй параметр изобразить в Лотус скриптах и что это за объект, массив, лист... ????
Что в Лотус скриптах будет идентично строке {'project': 'TST', 'type': '1', 'summary': 'Issue created with Python!'} в Python?)))
т.е. опять же не пойму что функции подать на вход(((

<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">no-highlight</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='""'>Sub Initialize
Dim wsdl As String
Dim client As Variant
Dim result As Variant

Dim startTime As Single
Dim endTime As Single

startTime = Timer
wsdl = "http://server:8080/rpc/soap/jirasoapservice-v2?wsdl"

'** try to use MSSOAP 3.0, if available
On Error Resume Next
Set client = CreateObject("MSSOAP.SoapClient30")
On Error Goto processError

'** if not, use whatever version is on the workstation
If (Err > 0) Then
Err = 0
Set client = CreateObject("MSSOAP.SoapClient")
End If
Call client.MSSoapInit(wsdl)

Dim password As String
Dim jirauser As String

jirauser="admin"
password=psw"

Dim auth As Variant
auth = client.login(jirauser, password)

Dim issue As Variant
Set issue = client.getIssue(auth, "TSTPR-1")

Messagebox PrintXmlResult(issue, " -> ") 'данный метод работает

Dim newissue As Variant

Set newissue = client.createIssue(auth, {'project': 'TST', 'type': '1', 'summary': 'Issue created with Python!'}) 'здесь вываливает ошибку если использовать такой же си нтаксис как в Python...[/CODE]
Какая конструкция на Lotus script будет идентична строке

{'project': 'TST', 'type': '1', 'summary': 'Issue created with Python!'}

в Python???

Массив, Лист?? Какого вида?

Откопал ещё пример на пхп:

$action = array($token, array('project'=>"TST",'type'=>'1','summary'=>''Issue created with PHP!''));
$issue = $client->call('createIssue', $action);

Опять же непонятно как будет выглядеть эта конструкия -
Код:
array('project'=>"TST",'type'=>'1','summary'=>''Issue created with PHP!'')
- на LS??
 

Gor

Well-Known Member
07.06.2005
517
2
#6
Всё получилось, всем спасибо.

Пошёл путём общения Lotus -> Jira через RPC Jira плагин, вебсервис.

Для создания Java классов и чтения WSDL файла использовал технологию Apache Axis. Куда впрочем меня все и посылали - http://www.ibm.com/developerworks/ru/libra...no-webservices/

В итоге у меня получился Lotus Java агент, который может создавать новые Issue, делать Update итд итп, в общем использовать всю функциональность методов веб сервиса http://docs.atlassian.com/software/jira/do...oapService.html

Все проблемы с несовпадением типов данных, появлением каких то непонятных ошибок, которые были при использовании Lotus Script и Soap Toolkit-a естественно пропали))

Если кому либо будет интересно, чуть позже могу выложить конечный код агента.
 

dionio

New Member
24.08.2010
1
0
#7
Да, если можете, выложите пожалуйста код агента. Сгенерить стабы по wsdl, в принципе, не проблема, но вот как потом скрестить его с Lotus - не совсем понятно, а мигрировать с Lotus на Jira в скором времени придется.
 

Gor

Well-Known Member
07.06.2005
517
2
#8
Извиняюсь, что с большим опозданием (был отвлечён на другие проекты не имеющие отношения к Лотусу и с некоторым сожалением в скором времени моё общение с данной платформой сведётся к минимуму)

но как говорится - лучше поздно чем...))

Lotus -> Jira через RPC Jira плагин, вебсервис

Про установку Apache Axis выше помоему писалось, поэтому не буду на этом останавливаться. Сгенерить стабы по wsdl труда не составит и подключить библиотеку к агенту.

Агент умеет создавать новые Issue в Jir-e, запускается он по WQS из нового документа.
Собирает в документе необходимые поля, аттачменты, создаёт новый Issue в Jira и возвращает в Лотусовый документ номер Issue в Jira.
(поля в нашей версии Jira есть как Custom, так и системные - по коду это видно)
Из кода удалять ничего не стал так что даже название Лотусовых полей там своё родное.

Для движения Issue по Transitions из Лотуса мы используем - service.progressWorkflowAction(sc, key, Transition, remoteFields);
Можно организовать по аналогии.

<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'>import lotus.domino.*;

import java.net.URL;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

import com.atlassian.jira.rpc.exception.*;
import com.atlassian.jira.rpc.soap.beans.*;

import jiraserver.rpc.soap.jirasoapservice_v2.*;

import java.io.*;
import javax.xml.parsers.*;

import org.w3c.dom.*;
import org.xml.sax.*;

import java.io.StringReader;

import java.util.Calendar;


import java.util.Vector;

public class JavaAgent extends AgentBase {

public void NotesMain() {

try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
lotus.domino.Document doc = agentContext.getDocumentContext();
Database db = agentContext.getCurrentDatabase();

URL endpoint = new URL("http://jiraserver:8080/rpc/soap/jirasoapservice-v2?wsdl");


Service service1 = new Service();
JirasoapserviceV2SoapBindingStub service = new JirasoapserviceV2SoapBindingStub(endpoint,service1);

String sc = service.login("login","password");

String VC = doc.getItemValueString("VC"); //Value Chain в новую заявку
//String commentapp = doc.getItemValueString("Comment"); //comment

String System = doc.getItemValueString("System"); //System/Project
String SystemKey = doc.getItemValueString("syskey"); //System/Project/ключ проекта

String Originator = doc.getItemValueString("CreatedBy_InBehalf"); //Originator
lotus.domino.Document docPerson = getPersonDoc(Originator);
if (docPerson != null) {
Originator = "[" + Originator + "|" + docPerson.getHttpURL() + "]";
}

String OriginatorDep = doc.getItemValueString("CreatedBy_InBehalf_Department"); //Originator's department
String Subject = doc.getItemValueString("Subject"); //Subject
String Type = doc.getItemValueString("TypeForJira"); //doc.getItemValueString("Type2"); //Type
// String Project = doc.getItemValueString("AppProject"); //Привязанность к проекту
String IntrNum = doc.getItemValueString("Number"); //Интранет номер
String AssToGroup = doc.getItemValueString("ITAGroup"); //Assign To Group
String iLink = doc.getHttpURL();
String strBody = doc.getItemValueString("strBody_Request");
String strAct = doc.getItemValueString("RegAct");
String strDateComing = doc.getItemValueString("DateOfComing");



RemoteIssue rIssue = testCreateIssue(service,sc,System,VC,SystemKey,Originator,OriginatorDep,Subject,Type,IntrNum
, strBody, AssToGroup, iLink, strAct, strDateComing);//метод для создания нового Issue.

String issueKey = rIssue.getKey();

doc.replaceItemValue("JiraIssueNum", issueKey);

doc.save(true, false);

String[] fNames =getFilenames(doc);
String[] arrData;
if (!(fNames[0].equals(""))) {
arrData = getBase64Data(doc);
service.addBase64EncodedAttachmentsToIssue(sc, issueKey, fNames, arrData);
arrData = null;
}

fNames = null;
arrData = null;
endpoint = null;
service1 = null;
sc = null;
service = null;

docPerson.recycle();
doc.recycle();
db.recycle();
agentContext.recycle();
session.recycle();


} catch(Exception e) {
e.printStackTrace();
}
}

private static RemoteIssue testCreateIssue(JiraSoapService jiraSoapService, String token, String System, String VC, String SystemKey, String Originator, String OriginatorDep, String Subject, String Type, String IntrNum, String body, String AssToGroup, String iLink, String Act, String dComing)

throws java.rmi.RemoteException
{

//Timing timing = Timing.startTiming("CreateIssue");

try

{
// Create the issue

RemoteIssue issue = new RemoteIssue();

issue.setProject(SystemKey); //Проект
issue.setType(Type); //Тип
issue.setSummary(Subject); //Summary
issue.setPriority("6"); //Приоритет по умолчанию
issue.setDuedate(Calendar.getInstance());
issue.setAssignee("");

// Add custom fields
RemoteCustomFieldValue customFieldValue = new RemoteCustomFieldValue("customfield_10030", "", new String[] { System }); //System
RemoteCustomFieldValue customFieldValue2 = new RemoteCustomFieldValue("customfield_10004", "", new String[] { Originator }); //Originator
RemoteCustomFieldValue customFieldValue3 = new RemoteCustomFieldValue("customfield_10040", "", new String[] { OriginatorDep }); //OriginatorDep
RemoteCustomFieldValue customFieldValue4 = new RemoteCustomFieldValue("customfield_10008", "", new String[] { body }); //body
RemoteCustomFieldValue customFieldValue5 = new RemoteCustomFieldValue("customfield_10136", "", new String[] { VC }); //VC
RemoteCustomFieldValue customFieldValue6 = new RemoteCustomFieldValue("customfield_10000", "", new String[] { IntrNum }); //INTR Num
RemoteCustomFieldValue customFieldValue7 = new RemoteCustomFieldValue("customfield_10009", "", new String[] { AssToGroup }); //Assign To Group
RemoteCustomFieldValue customFieldValue8 = new RemoteCustomFieldValue("customfield_10080", "", new String[] { iLink }); //Intranet Link
RemoteCustomFieldValue customFieldValue9 = new RemoteCustomFieldValue("customfield_10111", "", new String[] { Act }); //Regulatory act #
RemoteCustomFieldValue customFieldValue10 = new RemoteCustomFieldValue("customfield_10110", "", new String[] { dComing }); //Date of coming into effect

RemoteCustomFieldValue[] customFieldValues = new RemoteCustomFieldValue[] { customFieldValue, customFieldValue2, customFieldValue3, customFieldValue4, customFieldValue5, customFieldValue6, customFieldValue7, customFieldValue8, customFieldValue9, customFieldValue10};
issue.setCustomFieldValues(customFieldValues);

RemoteIssue returnedIssue = jiraSoapService.createIssue(token, issue);

//final String issueKey = returnedIssue.getKey();

return returnedIssue;

}

finally

{

//timing.printTiming();
}
}

private static void testAddComment(JiraSoapService jiraSoapService, String token, final String issueKey, String bod)
throws java.rmi.RemoteException
{
// Timing timing = Timing.startTiming("AddComment");
try
{

// Adding a comment
final RemoteComment comment = new RemoteComment();
comment.setBody(bod);
jiraSoapService.addComment(token, issueKey, comment);

}
finally
{
// timing.printTiming();
}
}

private static void testUpdateIssue(JiraSoapService jiraSoapService, String token, final String issueKey)
throws java.rmi.RemoteException
{
// Update the issue
RemoteFieldValue[] actionParams = new RemoteFieldValue[]{
new RemoteFieldValue("summary", new String[] {"new Summary"}),
new RemoteFieldValue("type", new String[]{"1"}),
new RemoteFieldValue("priority", new String[]{"1"})};

jiraSoapService.updateIssue(token, issueKey, actionParams);
}

private lotus.domino.Document getPersonDoc(String userName) throws lotus.domino.NotesException {
try {
Session session = getSession();
Database db = session.getAgentContext().getCurrentDatabase();
Database dbPerson = session.getDatabase(db.getServer(), "phonebook.nsf");
View view = dbPerson.getView("ByName");

lotus.domino.Document docPerson = view.getDocumentByKey(userName);
return docPerson;
}
finally {
}


}

public String[] getFilenames( lotus.domino.Document doc) throws lotus.domino.NotesException {
try {
Session session = getSession();
Vector vf = session.evaluate("@AttachmentNames", doc);

String[] fn;
if (vf.elementAt(0).equals("")) {
fn = new String[1];
fn[0] = "";
} else {
fn = new String[vf.size()];
for (int i=0; i<vf.size(); i++)
{ fn = (String) vf.elementAt(i);
}
}

return fn;

}
finally {
}
}

public String[] getBase64Data( lotus.domino.Document doc) throws java.rmi.RemoteException {

try {
Session session = getSession();
DxlExporter exporter = session.createDxlExporter();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document domDoc = builder.parse(new InputSource(new StringReader( exporter.exportDxl(doc) )));

org.w3c.dom.Node node;
int fileCount = domDoc.getElementsByTagName("filedata").getLength();

String[] DataBase64;
if (fileCount == 0) {
DataBase64 = new String[1];
DataBase64[0] = "";
}
else {
DataBase64 = new String[ fileCount ];
for (int i=0; i < fileCount; i++) {
node = domDoc.getElementsByTagName("filedata").item(i).getFirstChild();

DataBase64[ i ] = node.getNodeValue();
}
}

factory = null;
builder = null;
node = null;
domDoc = null;
exporter.recycle();
return DataBase64;

}
catch(Exception e) {
e.printStackTrace();
return null;
}
}


}[/CODE]
P.S. Сильно не пинайте если это уже 10 раз где то обсуждалось и решение было выложено. ОООчень давно не был на форуме.