gateway/modules/workflows/methods/methodJira/actions/connectJira.py
2025-12-17 10:45:09 +01:00

139 lines
5.1 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Connect JIRA action for JIRA operations.
Connects to JIRA instance and creates ticket interface.
"""
import logging
import json
import uuid
from typing import Dict, Any
from modules.workflows.methods.methodBase import action
from modules.datamodels.datamodelChat import ActionResult, ActionDocument
from modules.shared.configuration import APP_CONFIG
logger = logging.getLogger(__name__)
@action
async def connectJira(self, parameters: Dict[str, Any]) -> ActionResult:
"""
Connect to JIRA instance and create ticket interface.
Parameters:
- apiUsername (str, required): JIRA API username/email
- apiTokenConfigKey (str, required): APP_CONFIG key name for JIRA API token
- apiUrl (str, required): JIRA instance URL (e.g., https://example.atlassian.net)
- projectCode (str, required): JIRA project code (e.g., "DCS")
- issueType (str, required): JIRA issue type (e.g., "Task")
- taskSyncDefinition (str or dict, required): Field mapping definition as JSON string or dict
Returns:
- ActionResult with ActionDocument containing connection ID
"""
try:
apiUsername = parameters.get("apiUsername")
if not apiUsername:
return ActionResult.isFailure(error="apiUsername parameter is required")
apiTokenConfigKey = parameters.get("apiTokenConfigKey")
if not apiTokenConfigKey:
return ActionResult.isFailure(error="apiTokenConfigKey parameter is required")
apiUrl = parameters.get("apiUrl")
if not apiUrl:
return ActionResult.isFailure(error="apiUrl parameter is required")
projectCode = parameters.get("projectCode")
if not projectCode:
return ActionResult.isFailure(error="projectCode parameter is required")
issueType = parameters.get("issueType")
if not issueType:
return ActionResult.isFailure(error="issueType parameter is required")
taskSyncDefinitionParam = parameters.get("taskSyncDefinition")
if not taskSyncDefinitionParam:
return ActionResult.isFailure(error="taskSyncDefinition parameter is required")
# Parse taskSyncDefinition
if isinstance(taskSyncDefinitionParam, str):
try:
taskSyncDefinition = json.loads(taskSyncDefinitionParam)
except json.JSONDecodeError as e:
return ActionResult.isFailure(error=f"taskSyncDefinition is not valid JSON: {str(e)}")
elif isinstance(taskSyncDefinitionParam, dict):
taskSyncDefinition = taskSyncDefinitionParam
else:
return ActionResult.isFailure(error=f"taskSyncDefinition must be a dict or JSON string, got {type(taskSyncDefinitionParam)}")
# Get API token from APP_CONFIG
apiToken = APP_CONFIG.get(apiTokenConfigKey)
if not apiToken:
errorMsg = f"{apiTokenConfigKey} not found in APP_CONFIG"
logger.error(errorMsg)
return ActionResult.isFailure(error=errorMsg)
# Create ticket interface
syncInterface = await self.services.ticket.connectTicket(
taskSyncDefinition=taskSyncDefinition,
connectorType="Jira",
connectorParams={
"apiUsername": apiUsername,
"apiToken": apiToken,
"apiUrl": apiUrl,
"projectCode": projectCode,
"ticketType": issueType,
},
)
# Store connection with unique ID
connectionId = str(uuid.uuid4())
self._connections[connectionId] = {
"interface": syncInterface,
"taskSyncDefinition": taskSyncDefinition,
"apiUrl": apiUrl,
"projectCode": projectCode,
}
logger.info(f"JIRA connection established: {connectionId} (Project: {projectCode})")
# Generate filename
workflowContext = self.services.chat.getWorkflowContext() if hasattr(self.services, 'chat') else None
filename = self._generateMeaningfulFileName(
"jira_connection",
"json",
workflowContext,
"connectJira"
)
# Create connection info document
connectionInfo = {
"connectionId": connectionId,
"apiUrl": apiUrl,
"projectCode": projectCode,
"issueType": issueType,
}
validationMetadata = self._createValidationMetadata(
"connectJira",
connectionId=connectionId,
apiUrl=apiUrl,
projectCode=projectCode
)
document = ActionDocument(
documentName=filename,
documentData=json.dumps(connectionInfo, indent=2),
mimeType="application/json",
validationMetadata=validationMetadata
)
return ActionResult.isSuccess(documents=[document])
except Exception as e:
errorMsg = f"Error connecting to JIRA: {str(e)}"
logger.error(errorMsg)
return ActionResult.isFailure(error=errorMsg)