Skip to content

Commit

Permalink
Merge pull request #142 from vmware/IAC-805-lazy-load-vro-categories
Browse files Browse the repository at this point in the history
IAC-805 Lazy Load of vRO Inventory Items
  • Loading branch information
akantchev authored Feb 14, 2024
2 parents 60bd232 + 691d499 commit 9b109bd
Show file tree
Hide file tree
Showing 24 changed files with 462 additions and 254 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"**/build/azure-pipelines/**/*.yml": "azure-pipelines"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript", "typescript"],

Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/DeletePackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class DeletePackage extends Command<void> {

constructor(config: ConfigurationManager, environment: EnvironmentManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext, node: PackageNode): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/FetchWorkflowSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class FetchWorkflowSchema extends Command<void> {

constructor(config: ConfigurationManager, environment: EnvironmentManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext, node: WorkflowNode): Promise<void> {
Expand Down
105 changes: 58 additions & 47 deletions extension/src/client/command/RunAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,53 +147,17 @@ export class RunAction extends Command<void> {
}

private async getScriptContent(document: vscode.TextDocument): Promise<string> {
if (document.languageId === "javascript") {
return document.getText()
}

if (document.languageId === "typescript") {
let inputFilePath = document.uri.fsPath
let inputFileName = path.basename(inputFilePath)
let tsNamespace: string | undefined
let rootPath: string
let srcPath: string

if (!document.isUntitled) {
const workspacePath = vscode.workspace.getWorkspaceFolder(document.uri)
if (!workspacePath) {
throw new Error(`File ${inputFileName} is not part of the workspace`)
}

rootPath = workspacePath.uri.fsPath
srcPath = path.join(rootPath, "src")
const pomFilePath = path.join(workspacePath.uri.fsPath, "pom.xml")

if (!fs.existsSync(pomFilePath)) {
throw new Error(`Missing pom.xml in workspace ${workspacePath.name}`)
}

const pomFile = new PomFile(pomFilePath)
tsNamespace = `${pomFile.groupId}.${pomFile.artifactId}`
} else {
rootPath = tmp.dirSync({ prefix: "o11n-ts-" }).name
srcPath = path.join(rootPath, "src")
inputFileName = inputFileName.endsWith(".ts") ? inputFileName : `${inputFileName}.ts`
inputFilePath = path.join(srcPath, inputFileName)
fs.mkdirpSync(path.dirname(inputFilePath))
fs.writeFileSync(inputFilePath, document.getText(), { encoding: "utf8" })
switch (document.languageId) {
case "javascript": {
return document.getText()
}
case "typescript": {
return this.getTypescriptContent(document)
}
default: {
return Promise.reject(new Error(`Unsupported language ID: '${document.languageId}'`))
}

this.outputChannel.appendLine(`# Compiling ${inputFileName}`)
const tsFileRelativePath = path.relative(srcPath, inputFilePath)
this.logger.debug(`Input TS file: ${inputFilePath}`)
const outputFilePath = await this.compileFile(tsFileRelativePath, rootPath, tsNamespace)
this.logger.debug(`Output JS file: ${outputFilePath}`)
const scriptContent = fs.readFileSync(outputFilePath, { encoding: "utf8" })

return scriptContent
}

return Promise.reject(`Unsupported language ID: ${document.languageId}`)
}

/**
Expand All @@ -213,8 +177,55 @@ export class RunAction extends Command<void> {
command += ` -n ${namespace}`
}
await proc.exec(command, { cwd: projectDirPath }, this.logger)

return path.join(outputDir, inputFile.replace(/\.ts$/, ".js"))
}

/**
* Return the typescript content of a vscode text document.
* @param document - reference to the vscode document.
*
* @returns the compiled javascript from the typescript document.
*/
private async getTypescriptContent(document: vscode.TextDocument): Promise<string> {
let inputFilePath = document.uri.fsPath
let inputFileName = path.basename(inputFilePath)
let tsNamespace: string | undefined
let rootPath: string
let srcPath: string

if (!document.isUntitled) {
const workspacePath = vscode.workspace.getWorkspaceFolder(document.uri)
if (!workspacePath) {
throw new Error(`File ${inputFileName} is not part of the workspace`)
}
rootPath = workspacePath.uri.fsPath
srcPath = path.join(rootPath, "src")
const pomFilePath = path.join(workspacePath.uri.fsPath, "pom.xml")
if (!fs.existsSync(pomFilePath)) {
throw new Error(`Missing pom.xml in workspace ${workspacePath.name}`)
}

const pomFile = new PomFile(pomFilePath)
tsNamespace = `${pomFile.groupId}.${pomFile.artifactId}`
} else {
rootPath = tmp.dirSync({ prefix: "o11n-ts-" }).name
srcPath = path.join(rootPath, "src")
inputFileName = inputFileName.endsWith(".ts") ? inputFileName : `${inputFileName}.ts`
inputFilePath = path.join(srcPath, inputFileName)
fs.mkdirpSync(path.dirname(inputFilePath))
fs.writeFileSync(inputFilePath, document.getText(), { encoding: "utf8" })
}

this.outputChannel.appendLine(`# Compiling ${inputFileName}`)
const tsFileRelativePath = path.relative(srcPath, inputFilePath)
this.logger.debug(`Input TS file: ${inputFilePath}`)
const outputFilePath = await this.compileFile(tsFileRelativePath, rootPath, tsNamespace)
this.logger.debug(`Output JS file: ${outputFilePath}`)
const scriptContent = fs.readFileSync(outputFilePath, { encoding: "utf8" })

return scriptContent
}
}

class ActionRunner {
Expand All @@ -225,7 +236,7 @@ class ActionRunner {
private executionToken: string

constructor(config: ConfigurationManager, private environment: EnvironmentManager) {
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
this.mavenProxy = new MavenCliProxy(environment, config.vrdev.maven, this.logger)
}

Expand Down Expand Up @@ -296,7 +307,7 @@ class ActionRunner {
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath)
}

// exec
await this.mavenProxy.copyDependency(
"com.vmware.pscoe.o11n",
"exec",
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/ShowActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ShowActions extends Command<void> {

constructor(environment: EnvironmentManager, private config: ConfigurationManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/ShowConfigurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ShowConfigurations extends Command<void> {

constructor(environment: EnvironmentManager, config: ConfigurationManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/ShowResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ShowResources extends Command<void> {

constructor(environment: EnvironmentManager, config: ConfigurationManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/command/ShowWorkflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ShowWorkflows extends Command<void> {

constructor(environment: EnvironmentManager, config: ConfigurationManager) {
super()
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

async execute(context: vscode.ExtensionContext): Promise<void> {
Expand Down
54 changes: 28 additions & 26 deletions extension/src/client/command/TriggerCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import { AutoWire, Logger, sleep } from "@vmware/vrdt-common"
import { remote } from "@vmware/vro-language-server"
import * as vscode from "vscode"
import { LanguageClient } from "vscode-languageclient"
import { CollectionStatus } from "packages/node/vro-language-server/src/server/request/collection/ServerCollection"

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v16.x on ubuntu-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v14.x on ubuntu-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v16.x on windows-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v14.x on windows-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v16.x on ubuntu-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v14.x on ubuntu-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v16.x on windows-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

Check warning on line 10 in extension/src/client/command/TriggerCollection.ts

View workflow job for this annotation

GitHub Actions / Node.js v14.x on windows-latest

Unable to resolve path to module 'packages/node/vro-language-server/src/server/request/collection/ServerCollection'

import { Commands } from "../constants"
import { Commands, LanguageServerConfig } from "../constants"
import { LanguageServices } from "../lang"
import { Command } from "./Command"

Expand All @@ -30,46 +32,46 @@ export class TriggerCollection extends Command<void> {
const languageClient = this.languageServices.client

if (!languageClient) {
this.logger.warn("The vRO language server is not running")
this.logger.warn(`The ${LanguageServerConfig.DisplayName} is not running`)
return
}

await vscode.commands.executeCommand(Commands.EventCollectionStart)

vscode.window.withProgress(
{
location: vscode.ProgressLocation.Window,
title: "vRO hint collection"
},
progress => {
async progress => {
return new Promise<void>(async (resolve, reject) => {
await languageClient.sendRequest(remote.server.triggerVroCollection, false)
let status = await languageClient.sendRequest(remote.server.giveVroCollectionStatus)

while (status && !status.finished) {
this.logger.info("Collection status:", status)
progress.report(status)
await sleep(1000)
status = await languageClient.sendRequest(remote.server.giveVroCollectionStatus)
}

this.logger.info("Collection finished:", status)

const status: CollectionStatus = await this.triggerVroDataCollection(languageClient, progress)
if (status.error !== undefined) {
await vscode.commands.executeCommand(Commands.EventCollectionError, status.error)

if (status.data.hintsPluginBuild === 0) {
vscode.window.showErrorMessage(
"The vRO Hint plug-in is not installed on the configured vRO server"
)
}
} else {
await vscode.commands.executeCommand(Commands.EventCollectionSuccess)
reject(new Error(`Failed to trigger data collection from vRO: ${status.error}`))
}

resolve()
})
}
)
}

private async triggerVroDataCollection(languageClient: LanguageClient, progress: any): Promise<CollectionStatus> {
await languageClient.sendRequest(remote.server.triggerVroCollection, false)
let status = await languageClient.sendRequest(remote.server.giveVroCollectionStatus)

// wait for status change
while (status && !status.finished) {
this.logger.info("Collection status:", status)
progress.report(status)
await sleep(LanguageServerConfig.SleepTime)
status = await languageClient.sendRequest(remote.server.giveVroCollectionStatus)
}
// check for error response
if (status.error !== undefined) {
await vscode.commands.executeCommand(Commands.EventCollectionError, status.error)
return status
}
await vscode.commands.executeCommand(Commands.EventCollectionSuccess)

return status
}
}
8 changes: 8 additions & 0 deletions extension/src/client/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,11 @@ export enum ProjectArchetypes {
VraNg = "com.vmware.pscoe.vra-ng:vra-ng-package",
Polyglot = "com.vmware.pscoe.polyglot:polyglot-project"
}

export enum LanguageServerConfig {
Port = 6014,
LoadType = "nolazy",
NodeType = "node-ipc",
DisplayName = "vRO Language Server",
SleepTime = 1000
}
15 changes: 9 additions & 6 deletions extension/src/client/lang/LanguageServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { remote } from "@vmware/vro-language-server"
import * as vscode from "vscode"
import * as client from "vscode-languageclient"

import { OutputChannels } from "../constants"
import { LanguageServerConfig, OutputChannels } from "../constants"
import { Registrable } from "../Registrable"
import { ConfigurationManager, EnvironmentManager } from "../system"

Expand Down Expand Up @@ -82,20 +82,23 @@ export class LanguageServices implements Registrable, vscode.Disposable {
? path.join(module, "dist", "langserver.js")
: path.join(module, "out", "server", "langserver.js")

this.logger.info(`Starting vRO language server on port 6014`)
this.logger.info(`Starting vRO language server on port '${LanguageServerConfig.Port}'`)

const serverOptions = {
run: {
module: executable,
transport: client.TransportKind.ipc,
args: ["--node-ipc"],
args: [`--${LanguageServerConfig.NodeType}`],
options: { cwd: module }
},
debug: {
module: executable,
transport: client.TransportKind.ipc,
args: ["--node-ipc"],
options: { cwd: module, execArgv: ["--nolazy", "--inspect=6014"] }
args: [`--${LanguageServerConfig.NodeType}`],
options: {
cwd: module,
execArgv: [`--${LanguageServerConfig.LoadType}`, `--inspect=${LanguageServerConfig.Port}`]
}
}
}

Expand All @@ -119,6 +122,6 @@ export class LanguageServices implements Registrable, vscode.Disposable {
]
}
}
return new client.LanguageClient("vRO LS", serverOptions, clientOptions)
return new client.LanguageClient(LanguageServerConfig.DisplayName, serverOptions, clientOptions)
}
}
2 changes: 1 addition & 1 deletion extension/src/client/provider/content/ContentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class ContentProvider implements vscode.TextDocumentContentProvider, Regi
private readonly logger = Logger.get("ContentProvider")

constructor(environment: EnvironmentManager, config: ConfigurationManager) {
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

dispose() {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/provider/explorer/ExplorerProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class ExplorerProvider implements vscode.TreeDataProvider<AbstractNode>,
readonly onDidChangeTreeData: vscode.Event<AbstractNode | undefined> = this.onDidChangeTreeDataEmitter.event

constructor(environment: EnvironmentManager, private config: ConfigurationManager) {
this.restClient = new VroRestClient(config, environment)
this.restClient = new VroRestClient(config)
}

register(context: vscode.ExtensionContext): void {
Expand Down
2 changes: 1 addition & 1 deletion extension/src/client/system/ConfigurationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Registrable } from "../Registrable"

@AutoWire
export class ConfigurationManager extends BaseConfiguration implements Registrable {
private homeDir = process.env[process.platform === "win32" ? "USERPROFILE" : "HOME"] || "~"
private homeDir = process.env[process.platform === "win32" ? "USERPROFILE" : "HOME"] ?? "~"
private readonly logger = Logger.get("ConfigurationManager")

readonly settingsXmlPath: string = path.resolve(this.homeDir, ".m2", "settings.xml")
Expand Down
16 changes: 8 additions & 8 deletions extension/src/client/ui/StatusBarController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ export class StatusBarController implements Registrable, vscode.Disposable {
this.collectionStatus.dispose()
}

private onConfigurationOrProfilesChanged() {
const currentProfileName = this.config.hasActiveProfile() ? this.config.activeProfile.get("id") : undefined

if (this.verifyConfiguration() && currentProfileName !== this.profileName && this.env.hasRelevantProject()) {
vscode.commands.executeCommand(Commands.TriggerServerCollection)
}
}

verifyConfiguration(): boolean {
this.profileName = this.config.hasActiveProfile() ? this.config.activeProfile.get("id") : undefined
this.logger.info(`Verifying configuration for active profile ${this.profileName}`)
Expand Down Expand Up @@ -96,6 +88,14 @@ export class StatusBarController implements Registrable, vscode.Disposable {
return false
}

private onConfigurationOrProfilesChanged() {
const currentProfileName = this.config.hasActiveProfile() ? this.config.activeProfile.get("id") : undefined

if (this.verifyConfiguration() && currentProfileName !== this.profileName && this.env.hasRelevantProject()) {
vscode.commands.executeCommand(Commands.TriggerServerCollection)
}
}

private onCollectionStart() {
this.collectionButton.text = "$(watch) "
this.collectionButton.command = Commands.TriggerServerCollection
Expand Down
Loading

0 comments on commit 9b109bd

Please sign in to comment.