Skip to content

Commit

Permalink
IJMP-1832-Do-not-reconnect-on-CredentialsNotFound
Browse files Browse the repository at this point in the history
  • Loading branch information
ATsikhamirau committed Sep 24, 2024
1 parent a74be98 commit 5f79048
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ class PurgeJobAction : AnAction() {
cancellable = true
) {
runCatching {
service<DataOpsManager>().performOperation(
DataOpsManager.getService().performOperation(
operation = PurgeJobOperation(
request = BasicPurgeJobParams(jobStatus.jobName, jobStatus.jobId),
connectionConfig = connectionConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,8 @@ import eu.ibagroup.formainframe.explorer.ExplorerUnit
import eu.ibagroup.formainframe.explorer.UNITS_CHANGED
import eu.ibagroup.formainframe.explorer.WorkingSet
import eu.ibagroup.formainframe.telemetry.NotificationsService
import eu.ibagroup.formainframe.utils.castOrNull
import eu.ibagroup.formainframe.utils.*
import eu.ibagroup.formainframe.utils.crudable.EntityWithUuid
import eu.ibagroup.formainframe.utils.getAncestorNodes
import eu.ibagroup.formainframe.utils.runInEdtAndWait
import eu.ibagroup.formainframe.utils.rwLocked
import eu.ibagroup.formainframe.utils.subscribe
import eu.ibagroup.formainframe.vfs.MFBulkFileListener
import eu.ibagroup.formainframe.vfs.MFVFilePropertyChangeEvent
import eu.ibagroup.formainframe.vfs.MFVirtualFile
Expand Down Expand Up @@ -475,7 +471,7 @@ abstract class ExplorerTreeView<Connection : ConnectionConfigBase, U : WorkingSe
* For USS files only
*/
fun updateAttributesForChildrenInEditor(renamedFile: VirtualFile, newName: String) {
val dataOpsManager = DataOpsManager.instance
val dataOpsManager = DataOpsManager.getService()
val parentAttributes = dataOpsManager.tryToGetAttributes(renamedFile)
val fileEditorManager = FileEditorManager.getInstance(project)
val openFiles = fileEditorManager.openFiles
Expand Down
30 changes: 20 additions & 10 deletions src/main/kotlin/eu/ibagroup/formainframe/tso/TSOWindowFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.intellij.ui.content.ContentManagerListener
import com.intellij.util.messages.Topic
import eu.ibagroup.formainframe.dataops.DataOpsManager
import eu.ibagroup.formainframe.dataops.exceptions.CallException
import eu.ibagroup.formainframe.dataops.exceptions.CredentialsNotFoundForConnection
import eu.ibagroup.formainframe.dataops.operations.MessageData
import eu.ibagroup.formainframe.dataops.operations.MessageType
import eu.ibagroup.formainframe.dataops.operations.TsoOperation
Expand Down Expand Up @@ -347,16 +348,25 @@ class TSOWindowFactory : ToolWindowFactory, PossiblyDumbAware, DumbAware {
processHandler.notifyTextAvailable(parseTSODataResponse(response), ProcessOutputType.STDOUT)
}
}.onFailure {
processHandler.notifyTextAvailable(
"Unsuccessful execution of the TSO request. Connection was broken.\n",
ProcessOutputType.STDOUT
)
executeTsoReconnectWithTimeout(
timeout = session.getTSOSessionConfig().timeout,
maxAttempts = session.getTSOSessionConfig().maxAttempts,
tsoConsole = console
) {
wrapInlineCall { sendTopic(SESSION_RECONNECT_TOPIC, project).reconnect(project, console, session) }
if (it is CredentialsNotFoundForConnection) {
processHandler.notifyTextAvailable(
"Unable to obtain the connection information for connection=${session.getConnectionConfig()}.\n Session will be closed.",
ProcessOutputType.STDOUT
)
session.markSessionUnresponsive()
processHandler.destroyProcess()
} else {
processHandler.notifyTextAvailable(
"Unsuccessful execution of the TSO request. Connection was broken.\n",
ProcessOutputType.STDOUT
)
executeTsoReconnectWithTimeout(
timeout = session.getTSOSessionConfig().timeout,
maxAttempts = session.getTSOSessionConfig().maxAttempts,
tsoConsole = console
) {
wrapInlineCall { sendTopic(SESSION_RECONNECT_TOPIC, project).reconnect(project, console, session) }
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ import eu.ibagroup.formainframe.testutils.testServiceImpl.TestDataOpsManagerImpl
import eu.ibagroup.formainframe.vfs.MFVirtualFile
import io.kotest.assertions.assertSoftly
import io.kotest.matchers.shouldBe
import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkConstructor
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.unmockkAll
import io.mockk.*
import kotlin.reflect.KFunction

class ExplorerTreeViewTestSpec : WithApplicationShouldSpec({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package eu.ibagroup.formainframe.tso

import com.intellij.execution.process.NopProcessHandler
import com.intellij.execution.process.ProcessOutputType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
Expand All @@ -25,6 +27,7 @@ import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl.MockToolWindow
import eu.ibagroup.formainframe.config.connect.ConnectionConfig
import eu.ibagroup.formainframe.dataops.DataOpsManager
import eu.ibagroup.formainframe.dataops.Operation
import eu.ibagroup.formainframe.dataops.exceptions.CredentialsNotFoundForConnection
import eu.ibagroup.formainframe.dataops.operations.MessageData
import eu.ibagroup.formainframe.dataops.operations.MessageType
import eu.ibagroup.formainframe.telemetry.NotificationsService
Expand Down Expand Up @@ -106,6 +109,53 @@ class TSOWindowFactoryTestSpec : WithApplicationShouldSpec({

val processHandler = spyk(NopProcessHandler())

should("should stop processing and shutdown processHandler in case of CredentialsNotFoundForConnection is thrown") {
// given
clearMocks(processHandler, verificationMarks = true, recordedCalls = true)
val dataOpsManager = ApplicationManager.getApplication().service<DataOpsManager>() as TestDataOpsManagerImpl
dataOpsManager.testInstance = object : TestDataOpsManagerImpl() {
override fun <R : Any> performOperation(operation: Operation<R>, progressIndicator: ProgressIndicator): R {
throw CredentialsNotFoundForConnection(ConnectionConfig())
}

}

val oldSessionResponse = TsoResponse(servletKey = "test-servletKey-1")
val session = TSOConfigWrapper(tsoSessionConfig, connectionConfig, oldSessionResponse)
val command = "TIME"
val messageType = mockk<MessageType>()
val messageData = mockk<MessageData>()

every { console.getProcessHandler() } returns processHandler
every { console.getTsoSession() } returns session
every { processHandler.notifyTextAvailable(any(), any()) } just Runs

// when
sendTopic(SESSION_COMMAND_ENTERED).processCommand(
project,
console,
session,
command,
messageType,
messageData,
processHandler
)

// then
verify(exactly = 1) {
processHandler.notifyTextAvailable(
"Unable to obtain the connection information for connection=${session.getConnectionConfig()}.\n Session will be closed.",
ProcessOutputType.STDOUT
)
}
verify(exactly = 1) {
processHandler.destroyProcess()
}
assertSoftly {
session.unresponsive shouldBe true
}
}

should("should reconnect to the tso session after unsuccessful execution of the command") {
// given
clearMocks(processHandler, verificationMarks = true, recordedCalls = true)
Expand Down

0 comments on commit 5f79048

Please sign in to comment.