Load InboundReferencedBeans for Insight add-on in JIRA - groovy

I'm working on Insight automation groovy script, but I got stuck in one point.
I have Insight object called "Agreement".
This object has Inbound References called "Services".
Each Agreement can have any number of Services. I need to get list of all Services for any Agreement. I found the method findObjectInboundReferencedBeans(int id) in the docs, but apparently, I'm missing something as when I run the script, I get an error in log:
AutomationRuleGroovyScriptAction, Unexpected error: No signature of method: com.riadalabs.jira.plugins.insight.channel.external.api.facade.impl.ObjectFacadeImpl.findObjectInboundReferencedBeans() is applicable for argument types: (java.lang.Integer) values: [15748]
Here is my script:
import com.atlassian.jira.component.ComponentAccessor;
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean;
import com.riadalabs.jira.plugins.insight.services.model.ObjectBean;
import com.riadalabs.jira.plugins.insight.services.model.MutableObjectAttributeBean;
import com.riadalabs.jira.plugins.insight.services.model.MutableObjectBean;
Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade")
def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass)
// def agreementStatusId = 2641
// def serviceStatusId = 2180
// def activeStatus = 1
// def stoppedStatus = 6
def attributeRef = "Status smlouvy"
def objectKey = object.getObjectKey();
def insightObject = objectFacade.loadObjectBean(objectKey)
int objectId = insightObject.getId()
----------------------------------
**// Here is the line I need help with
def inRef = objectFacade.findObjectInboundReferencedBeans(objectId)**
----------------------------------
def objectAttribute = objectFacade.loadObjectAttributeBean(objectId, attributeRef)
def objectAttributeValue = objectAttribute.getObjectAttributeValueBeans()[0].getValue()
log.warn(objectKey.toString())
log.warn(insightObject.toString())
log.warn(inRef)
I use this script also to get attribute value from Agreement object, which works fine.
I guess the problem is that I call the method on wrong object, but when I try to call in dirrectly on "insightObject" , I got the same error.
Thank you!

As answered on the Atlassian Community Page.
The method was removed with the release of Insight 5.1, see the upgrade notes here.
However, you can just use this to solve your issue:
def inRef = iqlFacade.findObjects(/object HAVING outboundReferences(Key = ${objectKey})/)

Related

PyTest how to properly mock imported ContextManager class and its function?

This is my sample code:
from path.lib import DBInterface
class MyClass:
def __init__(self):
self.something = "something"
def _my_method(self, some_key, new_setup):
with DBInterface(self.something) as ic:
current_setup = ic.get(some_key)
if current_setup != new_setup:
with DBInterface(self.something) as ic:
ic.set(new_setup)
def public_method(self, some_key, new_setup):
return self._my_method(some_key, new_setup)
(my actual code is bit more complex, but i cant put it here on public :)
Now, what I want to do is, I want to completely mock the imported class DBInterface, because I do not want my unittests to do anything in DB.
BUT I also need the ic.get(some_key) to return some value, or to be more precise, I need to set the value it returns, because thats the point of my unittests, to test if the method behave properly according to value returned from DB.
This is how far I got:
class TestMyClass:
def test_extractor_register(self, mocker):
fake_db = mocker.patch.object('my_path.my_lib.DBInterface')
fake_db.get.return_value = None
# spy_obj = mocker.spy(MyClass, "_my_method")
test_class = MyClass()
# Test new registration in _extractor_register
result = test_class.public_method(Tconf.test_key, Tconf.test_key_setup)
fake_db.assert_has_calls([call().__enter__().get(Tconf.test_key),
call().__enter__().set(Tconf.test_key, Tconf.test_key_setup)])
# spy_obj.assert_called_with(ANY, Tconf.test_key, Tconf.test_key_setup)
assert result.result_status.status_code == Tconf.status_ok.status_code
assert result.result_data == MyMethodResult.new_reg
But i am unable to set return value for call().__enter__().get(Tconf.test_key).
I have been trying many approaches:
fake_db.get.return_value = None
fake_db.__enter__().get.return_value = None
fake_db.__enter__.get = Mock(return_value=None)
mocker.patch.object(MyClass.DBInterface, "get").return_value = None
None of that is actually working and I am running out of options I can think about.
Without having more code or errors that are being produced, it's tough to provide a conclusive answer.
However, if you truly only need to specify a return value for set() I would recommend using MagicMock by virtue of patch --
from unittest.mock import patch
#patch("<MyClassFile>.DBInterface", autospec=True)
def test_extractor_register(mock_db):
mock_db.set.return_value = "some key"
# Rest of test code

Not able to add a project ID/name to a list in Jira/Groovy/Scriptrunner

The following question I present is the following: I'm doing a code that is been tested in the Scriptrunner console and tried into Jira. What I want to reach is the following: I have an issue in any project, at any moment a workflow transition allows me to copy the current issue and all the linked issues in a new project.
The cfProjectPicker is a custom field Project Picker that allows me to select a project.
What I'm having trouble right now on the code is the following:
1- projectKey is returning null valor but projectPicker is returning the correct project selected in the custom field.
2- createNewIssue is not allowing me to recognize the "params" field as a mutable issue, and it is a mutable (if I replace with newIssue it does take it)
3- the list "issuesCopied" is not allowing me to issuesCopied.id.toString() but I'm guessing is giving error due to the point 2.
Any help regarding the matter would be much appreciated because I'm not understanding what I'm doing wrong at moment.
def issueMgr = ComponentAccessor.getIssueManager();
def issueTypeSchemeManager = ComponentAccessor.getIssueTypeSchemeManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def projectMgr = ComponentAccessor.getProjectManager();
def groupManager = ComponentAccessor.getGroupManager();
def issueFactory = ComponentAccessor.getIssueFactory();
IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager();
def cfProjectPicker = customFieldManager.getCustomFieldObjectByName("Seleccionar Proyecto") //cf project picker
def issue = issueMgr.getIssueObject("MART1-1")
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() //User Admin
ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def currentIssue = issueFactory.getIssue()
//def issue = issueMgr.getIssueObject()
def newIssue = issueFactory.getIssue()
def exit = false
// Array list of the issues created to save them
List<String> issuesCopied = new ArrayList<>();
// ***** CREATE ISSUE *****
if (issuesCopied.isEmpty()){
String projectPicker = issue.getCustomFieldValue(cfProjectPicker)
log.error("Gengar")
log.error(projectPicker)
def projectKey = projectMgr.getProjectObjByKey(projectPicker)
log.error(projectKey)
newIssue.setProjectObject(projectKey)
newIssue.setIssueType(issue.getIssueType())
newIssue.setSummary(issue.getSummary())
newIssue.setDescription(issue.getDescription())
newIssue.setReporter(currentUser)
def params = ["issue":newIssue]
log.error(params)
def createNewIssue = issueMgr.createIssueObject(user,params);
issuesCopied.add(createNewIssue.id.toString())
}

Camunda: Use in an external Groovy script a provided Class

I want to use for scripting external Groovy Scripts.
To not copy a lot of code, I want to share classes.
I have:
- external_test.groovy
- Input.groovy
Running the external_test.groovy in Intellij works.
Input is a simple class:
package helpers
class Input {
String serviceConfig
String httpMethod
String path
LinkedHashMap headers = [:]
String payload
Boolean hasResponseJson
}
When the script is executed by Camunda, it cannot find the class:
import helpers.Input
...
And throws an Exception:
unable to resolve class helpers.Input # line 16, column 9. new helpers.Input(serviceConfig: "camundaService", ^ 1 error
It is listed in the Deployment:
Do I miss something or is this not supported?
I found a post in the Camunda forum, that helped me to solve this:
https://forum.camunda.org/t/groovy-files-cant-invoke-methods-in-other-groovy-files-which-are-part-of-same-deployment/7750/5
Here is the solution (that is not really satisfying - as it needs a lot of boilerplate code):
static def getScript(fileName, execution) {
def processDefinitionId = execution.getProcessDefinitionId()
def deploymentId = execution.getProcessEngineServices().getRepositoryService().getProcessDefinition(processDefinitionId).getDeploymentId()
def resource = execution.getProcessEngineServices().getRepositoryService().getResourceAsStream(deploymentId, fileName)
def scannerResource = new Scanner(resource, 'UTF-8')
def resourceAsString = scannerResource.useDelimiter('\\Z').next()
scannerResource.close()
GroovyShell shell = new GroovyShell()
return shell.parse(resourceAsString)
}
def helper = getScript("helpers/helper_classes.groovy", execution)
helper.myFunction("hello")

I cannot save rows to the DB with SQLAchemy + Pyramid

After hours of debugging, and because my organization does not have a lot of Python expertise, I am turning to this community for help.
I am trying to follow this tutorial with the goal of committing some data to the database. Although no errors get reported, I am also not saving any rows. What am I doing wrong?
When trying to commit using the db2Session, I get:
Transaction must be committed using the transaction manager.
But nowhere in the tutorial, do I see the transaction manager being used. I thought that this manager is bound using zope.sqlalchemy? Yet, nothing is happening otherwise. Help again would be really appreciated!
I have the following setup in my main function in a Pyramid App:
from sqlalchemy import engine_from_config
from .models import db1Session, db2Session
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
db1_engine = engine_from_config(settings, 'db1.')
db2_engine = engine_from_config(settings, 'db2.')
db1Session.configure(bind=db1_engine)
db2Session.configure(bind=db2_engine)
In .models/__init__py, I have:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (scoped_session, sessionmaker)
from zope.sqlalchemy import ZopeTransactionExtension
db1Session = scoped_session(sessionmaker(
extension=ZopeTransactionExtension()))
db2Session =
scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
In ./model/db2.py I have:
class PlateWellResult(Base):
__tablename__ = 'SomeTable'
__table_args__ = {"schema": 'some_schema'}
id = Column("ID", Integer, primary_key=True)
plate_id = Column("PlateID", Integer)
hit_group_id = Column("HitID", Integer, ForeignKey(
'some_schema.HitGroupID.ID'))
well_loc = Column("WellLocation", String)
The relevant bits of my saving function look like this. ./lib/db2_api.py:
def save_selected_rows(input_data, selected_rows, hit_group_id):
""" Wrapper method for saving selected rows """
# Assume I have all the right data below.
new_hit_row = PlateWellResult(
plate_id=master_plate_id,
hit_group_id=hit_group_id,
well_loc=selected_df_row.masterWellLocation)
db1Session.add(new_hit_row)
# When I try the row below:
# db2Session.commit()
# I get: Transaction must be committed using the transaction manager
# If I cancel the line above, nothing gets committed.
return 'Save successful.'
That function is called from my viewer:
#view_config(route_name='some_routename', renderer='json',
permission='create_hit_group')
def save_to_hitgroup(self):
""" Backend to AJAX call to save selected rows to a hit_group """
try:
# Assume that all values were checked and all the right
# parameters are passed
status = save_selected_rows(some_result,
selected_rows_list,
hitgroup_id)
json_resp = json.dumps({'errors': [],
'status': status})
return json_resp
except Exception as e:
json_resp = json.dumps({'errors': ['Error during saving. {'
'0}'.format(e)],
'status': []})
return json_resp
The comments above are good. I just wanted to summarize here.
The transaction manager is begun/committed/aborted by pyramid_tm. If you aren't using that then it's likely the issue.
You are also squashing possible database exceptions which need to be conveyed to the transaction manager. You can do this via transaction.abort() in the exception handler.

No such property: expected for class: Script1343 (in groovy script);

I am trying to retrieve data from oracle db but getting No such property: expected for class: Script1343 (in groovy script); error
import java.util.Properties;
import java.io.InputStream;
import groovy.sql.Sql;
def url = 'jdbc:oracle:thin:#//localhost:1521/TEST'
def user = 'DB'
def password = 'DB'
def driver = 'oracle.jdbc.driver.OracleDriver'
def sql = Sql.newInstance('url', 'User', 'password','oracle.jdbc.driver.OracleDriver')
sql.withStatement {
stmt -> stmt.queryTimeout = 30
print "Request TimeOut"
}
def rowNum = 0
sql.eachRow("SELECT DISTINCT CST_START_DT_PF,CST_ITEM_NUM_PF FROM COST "){ row ->
def first = row[0]
def middle = row.CST_START_DT_PF
def one = row.CST_ITEM_NUM_PF
assert expected[rowNum] == "$CST_START_DT_PF, $CST_ITEM_NUM_PF"
}
There are several things wrong. The specific error you asked about is the result of the following:
assert expected[rowNum] == "$CST_START_DT_PF, $CST_ITEM_NUM_PF"
You are referencing a variable expected which doesn't exist.
You didn't ask about the things below but other problems you are going to run into...
Referencing $CST_START_DT_PF and $CST_ITEM_NUM_PF is going to be a problem because they also don't exist, at least not in a way that your code will work.
You also are probably going to get unexpected results related to the fact that you are never incrementing rowNum.

Resources