Skip to content

Commit 71b495c

Browse files
authored
Merge pull request #209 from zowe/bugfix/IJMP-1923
IJMP-1923 Fixed IDE error in case of invalid zowe.config
2 parents 522702a + 4d091b8 commit 71b495c

File tree

5 files changed

+194
-136
lines changed

5 files changed

+194
-136
lines changed

src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt

+14-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
package org.zowe.explorer.config.connect.ui.zosmf
1616

17+
import com.google.gson.JsonSyntaxException
18+
import com.intellij.ide.DataManager
19+
import com.intellij.openapi.actionSystem.*
1720
import com.intellij.openapi.application.ApplicationManager
1821
import com.intellij.openapi.application.runInEdt
1922
import com.intellij.openapi.options.BoundSearchableConfigurable
@@ -34,6 +37,7 @@ import org.zowe.explorer.config.connect.Credentials
3437
import org.zowe.explorer.config.ws.FilesWorkingSetConfig
3538
import org.zowe.explorer.config.ws.JesWorkingSetConfig
3639
import org.zowe.explorer.config.ws.WorkingSetConfig
40+
import org.zowe.explorer.telemetry.NotificationsService
3741
import org.zowe.explorer.utils.crudable.getAll
3842
import org.zowe.explorer.utils.isThe
3943
import org.zowe.explorer.utils.runWriteActionInEdtAndWait
@@ -109,7 +113,16 @@ class ZOSMFConnectionConfigurable : BoundSearchableConfigurable("z/OSMF Connecti
109113
return
110114
}
111115

112-
val zoweConfig = parseConfigJson(configFile.inputStream)
116+
val zoweConfig = try {
117+
parseConfigJson(configFile.inputStream)
118+
} catch (e: JsonSyntaxException) {
119+
NotificationsService.errorNotification(
120+
e,
121+
project = DataManager.getInstance().getDataContext(panel).getData(PlatformDataKeys.PROJECT),
122+
custTitle = "Error with Zowe config file"
123+
)
124+
return
125+
}
113126
zoweConfig.extractSecureProperties(configFile.path.split("/").toTypedArray())
114127
kotlin.runCatching {
115128
zoweConfig.updateFromState(state)

src/main/kotlin/org/zowe/explorer/zowe/actions/UpdateZoweConfigAction.kt

+12-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package org.zowe.explorer.zowe.actions
1616

17+
import com.google.gson.JsonSyntaxException
1718
import com.intellij.openapi.actionSystem.ActionUpdateThread
1819
import com.intellij.openapi.actionSystem.AnActionEvent
1920
import com.intellij.openapi.actionSystem.CommonDataKeys
@@ -84,12 +85,17 @@ class UpdateZoweConfigAction : DumbAwareAction() {
8485
zoweConfigService.localZoweConfig
8586
else
8687
zoweConfigService.globalZoweConfig
87-
if (type == ZoweConfigType.LOCAL) {
88-
zoweConfigService.localZoweConfig = parseConfigJson(editor.document.text)
89-
zoweConfigService.localZoweConfig?.extractSecureProperties(vFile.path.split("/").toTypedArray())
90-
} else {
91-
zoweConfigService.globalZoweConfig = parseConfigJson(editor.document.text)
92-
zoweConfigService.globalZoweConfig?.extractSecureProperties(vFile.path.split("/").toTypedArray())
88+
try {
89+
if (type == ZoweConfigType.LOCAL) {
90+
zoweConfigService.localZoweConfig = parseConfigJson(editor.document.text)
91+
zoweConfigService.localZoweConfig?.extractSecureProperties(vFile.path.split("/").toTypedArray())
92+
} else {
93+
zoweConfigService.globalZoweConfig = parseConfigJson(editor.document.text)
94+
zoweConfigService.globalZoweConfig?.extractSecureProperties(vFile.path.split("/").toTypedArray())
95+
}
96+
} catch (ex: JsonSyntaxException) {
97+
e.presentation.isEnabledAndVisible = false
98+
return
9399
}
94100
val zoweState = zoweConfigService.getZoweConfigState(false, type = type)
95101
e.presentation.isEnabledAndVisible =

src/main/kotlin/org/zowe/explorer/zowe/service/ZoweConfigServiceImpl.kt

+80-106
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
package org.zowe.explorer.zowe.service
1616

17-
import com.intellij.notification.Notification
1817
import com.intellij.notification.NotificationGroupManager
1918
import com.intellij.notification.NotificationType
20-
import com.intellij.notification.Notifications
2119
import com.intellij.openapi.actionSystem.AnActionEvent
2220
import com.intellij.openapi.application.runReadAction
2321
import com.intellij.openapi.application.runWriteAction
@@ -38,6 +36,7 @@ import org.zowe.explorer.dataops.DataOpsManager
3836
import org.zowe.explorer.dataops.operations.InfoOperation
3937
import org.zowe.explorer.dataops.operations.ZOSInfoOperation
4038
import org.zowe.explorer.explorer.EXPLORER_NOTIFICATION_GROUP_ID
39+
import org.zowe.explorer.telemetry.NotificationsService
4140
import org.zowe.explorer.utils.crudable.find
4241
import org.zowe.explorer.utils.crudable.getAll
4342
import org.zowe.explorer.utils.runTask
@@ -64,9 +63,6 @@ import java.util.regex.Pattern
6463
import java.util.stream.Collectors
6564
import kotlin.collections.set
6665

67-
68-
const val ZOWE_CONFIG_NOTIFICATION_GROUP_ID = "org.zowe.explorerzowe.service.ZoweConfigNotificationGroupId"
69-
7066
const val ZOWE_PROJECT_PREFIX = "zowe-"
7167

7268
/**
@@ -123,22 +119,6 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
123119

124120
override var globalZoweConfig: ZoweConfig? = null
125121

126-
/**
127-
* Displays an error notification if an error was received.
128-
* @param t thrown error.
129-
* @param title error text.
130-
*/
131-
private fun notifyError(t: Throwable, title: String? = null) {
132-
Notifications.Bus.notify(
133-
Notification(
134-
ZOWE_CONFIG_NOTIFICATION_GROUP_ID,
135-
title ?: "Error with Zowe config file",
136-
t.message ?: t.toString(),
137-
NotificationType.ERROR
138-
)
139-
)
140-
}
141-
142122
/**
143123
* Checks project contains zowe.config.json. If zowe config presented
144124
* it will parse it and save to object model inside zoweConfig field.
@@ -162,7 +142,8 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
162142
}
163143
}
164144
} catch (e: Exception) {
165-
throw Exception("Cannot parse $type Zowe config file")
145+
NotificationsService.errorNotification(e, project = myProject, custTitle="Error with Zowe config file")
146+
return null
166147
}
167148
}
168149

@@ -208,8 +189,8 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
208189

209190
/**
210191
* Added notification about connection failure with action of force connection adding.
211-
* @param title - notification title.
212-
* @param content - notification content.
192+
* @param title notification title.
193+
* @param content notification content.
213194
* @return Nothing.
214195
*/
215196
private fun notifyUiOnConnectionFailure(title: String, content: String, type: ZoweConfigType) {
@@ -277,27 +258,23 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
277258
this.globalZoweConfig
278259
zoweConfig ?: throw Exception("Cannot get $type Zowe config")
279260

280-
var allPreparedConn = mutableListOf<ConnectionConfig>()
281-
if (checkConnection) {
282-
val failedURLs = mutableListOf<String>()
283-
allPreparedConn = testAndPrepareAllZosmfConnections(zoweConfig, type, failedURLs)
284-
if (failedURLs.isNotEmpty()) {
285-
val andMore = if (failedURLs.size > 3)
286-
"..."
287-
else
288-
""
289-
notifyUiOnConnectionFailure(
290-
"Connection failed to:",
291-
"${failedURLs.joinToString(separator = ", <p>")} ${andMore}",
292-
type
293-
)
294-
return
295-
}
261+
val (allPreparedConn, failedConnections) = testAndPrepareAllZosmfConnections(zoweConfig, type)
262+
if (checkConnection and failedConnections.isNotEmpty()) {
263+
val andMore = if (failedConnections.size > 3) "..." else ""
264+
notifyUiOnConnectionFailure(
265+
"Connection failed to:",
266+
"${failedConnections.map{it.url}.joinToString(separator = ", <p>")} $andMore",
267+
type
268+
)
296269
}
297-
for (zosmfConnection in allPreparedConn) {
270+
val conToAdd = if (checkConnection)
271+
allPreparedConn.subtract(failedConnections.toSet())
272+
else
273+
allPreparedConn
274+
conToAdd.forEach { zosmfConnection ->
298275
val connectionOpt = configCrudable.addOrUpdate(zosmfConnection)
299276
if (!connectionOpt.isEmpty) {
300-
var topic = if (type == ZoweConfigType.LOCAL)
277+
val topic = if (type == ZoweConfigType.LOCAL)
301278
LOCAL_ZOWE_CONFIG_CHANGED
302279
else
303280
GLOBAL_ZOWE_CONFIG_CHANGED
@@ -306,7 +283,7 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
306283
}
307284

308285
} catch (e: Exception) {
309-
notifyError(e)
286+
NotificationsService.errorNotification(e, project = myProject, custTitle="Error with Zowe config file")
310287
}
311288
}
312289

@@ -319,9 +296,9 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
319296
private fun prepareConnection(zosmfConnection: ZOSConnection, type: ZoweConfigType): ConnectionConfig {
320297
val username = zosmfConnection.user
321298
val password = zosmfConnection.password
322-
val zoweConnection = findExistingConnection(type, zosmfConnection.profileName)?.let {
323-
zosmfConnection.toConnectionConfig(it.uuid, it.zVersion, type = type)
324-
} ?: zosmfConnection.toConnectionConfig(UUID.randomUUID().toString(), type = type)
299+
val zoweConnection = findExistingConnection(type, zosmfConnection.profileName)
300+
?.let { zosmfConnection.toConnectionConfig(it.uuid, it.zVersion, type = type) }
301+
?: zosmfConnection.toConnectionConfig(UUID.randomUUID().toString(), type = type)
325302
CredentialService.getService().setCredentials(zoweConnection.uuid, username, password)
326303
return zoweConnection
327304
}
@@ -330,24 +307,25 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
330307
* Convert all zosmf connections from zowe config file to ConnectionConfig and tests them
331308
* @param zoweConfig
332309
* @param type of zowe config
333-
* @return list of URLs which did not pass the test
310+
* @return pair of lists, one is the connections list, the second is the list of URLs which did not pass the test
334311
*/
335312
private fun testAndPrepareAllZosmfConnections(
336313
zoweConfig: ZoweConfig,
337-
type: ZoweConfigType,
338-
failedURLs: MutableList<String>
339-
): MutableList<ConnectionConfig> {
340-
var allPreparedConn = mutableListOf<ConnectionConfig>()
341-
for (zosmfConnection in zoweConfig.getListOfZosmfConections()) {
342-
val zoweConnection = prepareConnection(zosmfConnection, type)
343-
try {
344-
testAndPrepareConnection(zoweConnection)
345-
} catch (t: Throwable) {
346-
failedURLs.add(zoweConnection.url)
314+
type: ZoweConfigType
315+
): Pair<List<ConnectionConfig>, List<ConnectionConfig>> {
316+
return zoweConfig.getListOfZosmfConections()
317+
.fold(
318+
mutableListOf<ConnectionConfig>() to mutableListOf<ConnectionConfig>()
319+
) { (allConnectionConfigs, failedURLs), zosmfConnection ->
320+
val zoweConnection = prepareConnection(zosmfConnection, type)
321+
try {
322+
testAndPrepareConnection(zoweConnection)
323+
} catch (t: Throwable) {
324+
failedURLs.add(zoweConnection)
325+
}
326+
allConnectionConfigs.add(zoweConnection)
327+
allConnectionConfigs to failedURLs
347328
}
348-
allPreparedConn.add(zoweConnection)
349-
}
350-
return allPreparedConn
351329
}
352330

353331
/**
@@ -384,7 +362,7 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
384362
}
385363

386364
} catch (e: Exception) {
387-
notifyError(e)
365+
NotificationsService.errorNotification(e, project = myProject, custTitle="Error with Zowe config file")
388366
}
389367
}
390368

@@ -434,18 +412,20 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
434412
val allConnections = configCrudable.getAll<ConnectionConfig>().toList()
435413
val allConnectionsNames: MutableList<String> = allConnections.map { it.name }.toMutableList()
436414

437-
allConnections.filter { it.zoweConfigPath == getZoweConfigLocation(myProject, type) }.forEach {
438-
var index = 1
439-
var newName = it.name
440-
while (allConnectionsNames.contains(newName)) {
441-
newName = it.name.plus(index.toString())
442-
index++
415+
allConnections
416+
.filter { it.zoweConfigPath == getZoweConfigLocation(myProject, type) }
417+
.forEach {
418+
var index = 1
419+
var newName = it.name
420+
while (allConnectionsNames.contains(newName)) {
421+
newName = it.name.plus(index.toString())
422+
index++
423+
}
424+
allConnectionsNames.add(newName)
425+
it.name = newName
426+
it.zoweConfigPath = null
427+
configCrudable.update(it)
443428
}
444-
allConnectionsNames.add(newName)
445-
it.name = newName
446-
it.zoweConfigPath = null
447-
configCrudable.update(it)
448-
}
449429
}
450430

451431
private fun createZoweSchemaJsonIfNotExists() {
@@ -490,51 +470,45 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService
490470
*/
491471
override fun getZoweConfigState(scanProject: Boolean, type: ZoweConfigType): ZoweConfigState {
492472
if (scanProject) {
493-
try {
494473
scanForZoweConfig(type)
495-
} catch (e: Exception) {
496-
notifyError(e)
497-
}
498474
}
499475
val zoweConfig = if (type == ZoweConfigType.LOCAL)
500476
localZoweConfig ?: return ZoweConfigState.NOT_EXISTS
501477
else
502478
globalZoweConfig ?: return ZoweConfigState.NOT_EXISTS
503479

504480
findAllZosmfExistingConnection(type) ?: return ZoweConfigState.NEED_TO_ADD
505-
var ret = ZoweConfigState.SYNCHRONIZED
506-
507-
for (zosConnection in zoweConfig.getListOfZosmfConections()) {
508-
val existingConnection =
509-
findExistingConnection(type, zosConnection.profileName)
510-
if (existingConnection == null)
511-
ret = setZoweConfigState(ret, ZoweConfigState.NEED_TO_ADD)
512-
else {
513-
val newConnectionList = zoweConfig.getListOfZosmfConections()
514-
.filter { it.profileName == getProfileNameFromConnName(existingConnection.name) }
515-
val newConnection = if (newConnectionList.isNotEmpty()) {
516-
newConnectionList[0].toConnectionConfig(
517-
existingConnection.uuid.toString(), existingConnection.zVersion, existingConnection.owner, type = type
518-
)
519-
} else {
520-
ret = setZoweConfigState(ret, ZoweConfigState.NEED_TO_ADD)
521-
continue
522-
}
523-
val zoweUsername = zosConnection.user
524-
val zowePassword = zosConnection.password
525-
526-
ret = if (
527-
existingConnection == newConnection
528-
&& CredentialService.getUsername(newConnection) == zoweUsername
529-
&& CredentialService.getPassword(newConnection) == zowePassword
530-
) {
531-
setZoweConfigState(ret, ZoweConfigState.SYNCHRONIZED)
481+
482+
return zoweConfig
483+
.getListOfZosmfConections()
484+
.fold(ZoweConfigState.SYNCHRONIZED) { prevZoweConfigState, zosConnection ->
485+
val existingConnection = findExistingConnection(type, zosConnection.profileName)
486+
val currZoweConfigState = if (existingConnection == null) {
487+
ZoweConfigState.NEED_TO_ADD
532488
} else {
533-
setZoweConfigState(ret, ZoweConfigState.NEED_TO_UPDATE)
489+
val newConnectionList = zoweConfig.getListOfZosmfConections()
490+
.filter { it.profileName == getProfileNameFromConnName(existingConnection.name) }
491+
if (newConnectionList.isNotEmpty()) {
492+
val newConnection = newConnectionList[0].toConnectionConfig(
493+
existingConnection.uuid, existingConnection.zVersion, existingConnection.owner, type = type
494+
)
495+
val zoweUsername = zosConnection.user
496+
val zowePassword = zosConnection.password
497+
if (
498+
existingConnection == newConnection
499+
&& CredentialService.getUsername(newConnection) == zoweUsername
500+
&& CredentialService.getPassword(newConnection) == zowePassword
501+
) {
502+
ZoweConfigState.SYNCHRONIZED
503+
} else {
504+
ZoweConfigState.NEED_TO_UPDATE
505+
}
506+
} else {
507+
ZoweConfigState.NEED_TO_ADD
508+
}
534509
}
510+
setZoweConfigState(prevZoweConfigState, currZoweConfigState)
535511
}
536-
}
537-
return ret
538512
}
539513

540514
/**

0 commit comments

Comments
 (0)