Skip to content

Commit b3f1590

Browse files
authored
Use v4 of the MicroProfile starter api (#59)
* Update to use v4 mp starter api * move project generation to starter api helper * Update wording in error messages Signed-off-by: Ryan Zegray <[email protected]>
1 parent ee6ddd3 commit b3f1590

8 files changed

+151
-74
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Change Log
22
All notable changes to the MicroProfile Starter extension will be documented below.
33

4+
## 0.2.5
5+
- MicroProfile 3.3
6+
- Support for generating a WildFly project
7+
- Better support for selecting a JavaSE version
8+
- Use version 4 of the MicroProfile Starter API
9+
410
## 0.2.4
511
- Use version 3 of the MicroProfile Starter API when generating a project
612
- Update dependencies

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# VS Code MicroProfile Starter Extension
22

33
[![Marketplace Version](https://vsmarketplacebadge.apphb.com/version/MicroProfile-Community.mp-starter-vscode-ext.svg "Current Release")](https://marketplace.visualstudio.com/items?itemName=MicroProfile-Community.mp-starter-vscode-ext)
4+
[![Marketplace Installs](https://vsmarketplacebadge.apphb.com/installs-short/MicroProfile-Community.mp-starter-vscode-ext.svg "Installs")](https://marketplace.visualstudio.com/items?itemName=MicroProfile-Community.mp-starter-vscode-ext)
45
[![Build Status](https://travis-ci.org/MicroShed/mp-starter-vscode-ext.svg?branch=master)](https://travis-ci.org/MicroShed/mp-starter-vscode-ext)
56

67
The MicroProfile Starter extension provides support for generating a MicroProfile Maven project with examples based on the Eclipse MicroProfile Starter project (https://start.microprofile.io/) by the MicroProfile community. You will be able to generate a project by choosing a MicroProfile version, server and specifications, such as CDI, Config, Health, Metrics, and more. The code for this extension is hosted under the MicroShed organization on GitHub.

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "mp-starter-vscode-ext",
33
"displayName": "MicroProfile Starter",
44
"description": "Generate Java Microservice Maven projects using Eclipse MicroProfile",
5-
"version": "0.2.4",
5+
"version": "0.2.5",
66
"publisher": "MicroProfile-Community",
77
"preview": true,
88
"license": "Apache-2.0",

src/commands/generateProject.ts

+44-60
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,12 @@ import * as vscode from "vscode";
22
import * as util from "../util/util";
33
import * as prompts from "../util/vscodePrompts";
44
import * as path from "path";
5-
import fetch from "node-fetch";
6-
import { MP_STARTER_API_ROOT, OPEN_NEW_PROJECT_OPTIONS, EXTENSION_USER_AGENT } from "../constants";
5+
import { OPEN_NEW_PROJECT_OPTIONS, ERRORS } from "../constants";
6+
import * as mpStarterApi from "../util/mpStarterApi";
77

88
export async function generateProject(): Promise<void> {
99
try {
10-
const mpSupportResponse = await fetch(`${MP_STARTER_API_ROOT}/supportMatrix`, {
11-
method: "GET",
12-
headers: {
13-
"User-Agent": EXTENSION_USER_AGENT,
14-
},
15-
});
16-
if (mpSupportResponse.status >= 400 && mpSupportResponse.status < 600) {
17-
throw new Error(`Bad response ${mpSupportResponse.status}: ${mpSupportResponse.statusText}`);
18-
}
19-
20-
const mpSupportMatrix = await mpSupportResponse.json();
21-
10+
const mpSupportMatrix = await mpStarterApi.getSupportMatrix();
2211
// mpConfigurations is a map of mp version -> mp configuration
2312
const mpConfigurations = mpSupportMatrix.configs;
2413
const allMpVersions = Object.keys(mpConfigurations);
@@ -44,18 +33,20 @@ export async function generateProject(): Promise<void> {
4433
return;
4534
}
4635

47-
const javaSEVersion = await prompts.askForJavaSEVersion(mpVersion, mpServer);
36+
// gets support information about which JavaSE versions / microprofile specs are supported by the
37+
// users selected mp server / mp version combination
38+
const { javaSEVersions, mpSpecs } = await mpStarterApi.getSupportedJavaAndSpecs(
39+
mpServer,
40+
mpVersion
41+
);
42+
43+
const javaSEVersion = await prompts.askForJavaSEVersion(javaSEVersions);
4844
if (javaSEVersion === undefined) {
4945
return;
5046
}
5147

52-
// ask user to pick a list of mp specifications to use for the given version of mp they selected
53-
const allSupportedSpecs = mpConfigurations[mpVersion].specs;
5448
const specDescriptions = mpSupportMatrix.descriptions;
55-
const mpSpecifications = await prompts.askForMPSpecifications(
56-
allSupportedSpecs,
57-
specDescriptions
58-
);
49+
const mpSpecifications = await prompts.askForMPSpecifications(mpSpecs, specDescriptions);
5950
if (mpSpecifications === undefined) {
6051
return;
6152
}
@@ -67,7 +58,7 @@ export async function generateProject(): Promise<void> {
6758

6859
const targetDirString = targetFolder.fsPath;
6960

70-
const requestPayload = {
61+
const projectOptions = {
7162
groupId: groupId,
7263
artifactId: artifactId,
7364
mpVersion: mpVersion,
@@ -80,61 +71,54 @@ export async function generateProject(): Promise<void> {
8071
// location to download the zip file
8172
const zipPath = path.join(targetDirString, zipName);
8273

83-
const requestOptions = {
84-
url: `${MP_STARTER_API_ROOT}/project`,
85-
method: "POST",
86-
headers: {
87-
"Content-Type": "application/json",
88-
"User-Agent": EXTENSION_USER_AGENT,
89-
},
90-
body: JSON.stringify(requestPayload),
91-
};
92-
9374
// show a progress bar as the zip file is being downloaded
9475
await vscode.window.withProgress(
9576
{
9677
location: vscode.ProgressLocation.Notification,
9778
title: "Generating the MicroProfile Starter project...",
9879
cancellable: false,
9980
},
100-
() => util.downloadFile(requestOptions, zipPath)
81+
() => mpStarterApi.downloadMPStarterProjectZip(projectOptions, zipPath)
10182
);
10283

84+
const targetDirFolder = path.join(targetDirString, artifactId);
85+
10386
try {
104-
const targetDirFolder = path.join(targetDirString, artifactId);
10587
await util.unzipFile(zipPath, targetDirString, targetDirFolder);
106-
try {
107-
await util.deleteFile(zipPath);
108-
} catch (e) {
109-
console.error(e);
110-
vscode.window.showErrorMessage(`Failed to delete file ${zipName}`);
111-
}
112-
113-
// open the unzipped folder in a new VS Code window
114-
const uriPath = vscode.Uri.file(targetDirFolder);
115-
// prompt user whether they want to add project to current workspace or open in a new window
116-
const selection = await vscode.window.showInformationMessage(
117-
"MicroProfile Starter project generated. Would you like to add your project to the current workspace or open it in a new window?",
118-
...[
119-
OPEN_NEW_PROJECT_OPTIONS.ADD_CURRENT_WORKSPACE,
120-
OPEN_NEW_PROJECT_OPTIONS.OPEN_NEW_WINDOW,
121-
]
122-
);
123-
if (selection === OPEN_NEW_PROJECT_OPTIONS.ADD_CURRENT_WORKSPACE) {
124-
vscode.workspace.updateWorkspaceFolders(0, 0, { uri: uriPath });
125-
} else if (selection === OPEN_NEW_PROJECT_OPTIONS.OPEN_NEW_WINDOW) {
126-
await vscode.commands.executeCommand("vscode.openFolder", uriPath, true);
127-
}
128-
} catch (err) {
129-
console.error(err);
130-
vscode.window.showErrorMessage("Failed to extract the MicroProfile Starter project.");
88+
} catch (e) {
89+
console.error(e);
90+
const err = new Error("Unable to extract MicroProfile Starter project");
91+
err.name = ERRORS.EXTRACT_PROJECT_ERROR;
92+
throw err;
93+
}
94+
95+
// if failed to delete the zip, no need to error out but show a warning to users
96+
try {
97+
await util.deleteFile(zipPath);
98+
} catch (e) {
99+
console.error(e);
100+
vscode.window.showErrorMessage(`Failed to delete file ${zipName}`);
101+
}
102+
103+
const uriPath = vscode.Uri.file(targetDirFolder);
104+
// prompt user whether they want to add project to current workspace or open in a new window
105+
const selection = await vscode.window.showInformationMessage(
106+
"MicroProfile Starter project generated. Add your project to the current workspace or open it in a new window?",
107+
...[OPEN_NEW_PROJECT_OPTIONS.ADD_CURRENT_WORKSPACE, OPEN_NEW_PROJECT_OPTIONS.OPEN_NEW_WINDOW]
108+
);
109+
if (selection === OPEN_NEW_PROJECT_OPTIONS.ADD_CURRENT_WORKSPACE) {
110+
vscode.workspace.updateWorkspaceFolders(0, 0, { uri: uriPath });
111+
} else if (selection === OPEN_NEW_PROJECT_OPTIONS.OPEN_NEW_WINDOW) {
112+
await vscode.commands.executeCommand("vscode.openFolder", uriPath, true);
131113
}
132114
} catch (e) {
133115
console.error(e);
134-
if (e.name === "FetchError") {
116+
if (e.name === ERRORS.FETCH_ERROR) {
135117
vscode.window.showErrorMessage(
136118
"Failed to connect to the MicroProfile Starter. Please check your network connection and try again."
137119
);
120+
} else if (e.name === ERRORS.EXTRACT_PROJECT_ERROR) {
121+
vscode.window.showErrorMessage("Failed to extract the MicroProfile Starter project");
138122
} else {
139123
vscode.window.showErrorMessage("Failed to generate a MicroProfile Starter project");
140124
}

src/constants.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
export const MP_STARTER_API_ROOT = "https://start.microprofile.io/api/3";
1+
export const MP_STARTER_API_ROOT = "https://start.microprofile.io/api/4";
22

33
export const MP_VERSION_LABELS: Record<string, string> = {
4+
MP33: "Version 3.3",
45
MP32: "Version 3.2",
56
MP30: "Version 3.0",
67
MP22: "Version 2.2",
@@ -17,7 +18,7 @@ export const MP_SERVER_LABELS: Record<string, string> = {
1718
PAYARA_MICRO: "Payara Micro",
1819
THORNTAIL_V2: "Thorntail Version 2",
1920
KUMULUZEE: "KumuluzEE",
20-
TOMEE: "Apache TomEE 8.00-M2",
21+
TOMEE: "Apache TomEE 8.00-M3",
2122
WILDFLY: "WildFly",
2223
WILDFLY_SWARM: "WildFly Swarm",
2324
QUARKUS: "Quarkus",
@@ -34,3 +35,8 @@ export const CONFIRM_OPTIONS = {
3435
YES: "Yes",
3536
NO: "No",
3637
};
38+
39+
export const ERRORS = {
40+
FETCH_ERROR: "FetchError",
41+
EXTRACT_PROJECT_ERROR: "ExtractProjectError",
42+
};

src/util/mpStarterApi.ts

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { MP_STARTER_API_ROOT, EXTENSION_USER_AGENT } from "../constants";
2+
import fetch from "node-fetch";
3+
import * as util from "../util/util";
4+
5+
interface MPVersionSupport {
6+
supportedServers: string[];
7+
specs: string[];
8+
}
9+
10+
interface SupportMatrix {
11+
configs: Record<string, MPVersionSupport>;
12+
descriptions: Record<string, string>;
13+
}
14+
15+
export async function getSupportMatrix(): Promise<SupportMatrix> {
16+
const mpSupportResponse = await fetch(`${MP_STARTER_API_ROOT}/supportMatrix`, {
17+
method: "GET",
18+
headers: {
19+
"User-Agent": EXTENSION_USER_AGENT,
20+
},
21+
});
22+
if (mpSupportResponse.status >= 400 && mpSupportResponse.status < 600) {
23+
throw new Error(`Bad response ${mpSupportResponse.status}: ${mpSupportResponse.statusText}`);
24+
}
25+
26+
return mpSupportResponse.json();
27+
}
28+
29+
interface SupportDetails {
30+
mpVersion: string;
31+
mpSpecs: string[];
32+
javaSEVersions: string[];
33+
}
34+
35+
export async function getSupportedJavaAndSpecs(
36+
serverName: string,
37+
microprofileVersion: string
38+
): Promise<SupportDetails> {
39+
const serverSupportResponse = await fetch(`${MP_STARTER_API_ROOT}/supportMatrix/servers`, {
40+
method: "GET",
41+
headers: {
42+
"User-Agent": EXTENSION_USER_AGENT,
43+
},
44+
});
45+
if (serverSupportResponse.status >= 400 && serverSupportResponse.status < 600) {
46+
throw new Error(
47+
`Bad response ${serverSupportResponse.status}: ${serverSupportResponse.statusText}`
48+
);
49+
}
50+
51+
const supportJSON = await serverSupportResponse.json();
52+
const serverInformation = supportJSON.configs[serverName];
53+
54+
const supportDetails: SupportDetails | undefined = serverInformation.find(
55+
(supportRecord: SupportDetails) => supportRecord.mpVersion === microprofileVersion
56+
);
57+
58+
if (supportDetails === undefined) {
59+
throw new Error("Unable to find supported MicroProfile specifications and Java versions");
60+
}
61+
62+
return supportDetails;
63+
}
64+
65+
interface StarterProjectOptions {
66+
groupId: string;
67+
artifactId: string;
68+
mpVersion: string;
69+
supportedServer: string;
70+
javaSEVersion: string;
71+
selectedSpecs: string[];
72+
}
73+
74+
export async function downloadMPStarterProjectZip(
75+
options: StarterProjectOptions,
76+
downloadLocation: string
77+
): Promise<void> {
78+
const requestOptions = {
79+
url: `${MP_STARTER_API_ROOT}/project`,
80+
method: "POST",
81+
headers: {
82+
"Content-Type": "application/json",
83+
"User-Agent": EXTENSION_USER_AGENT,
84+
},
85+
body: JSON.stringify(options),
86+
};
87+
88+
await util.downloadFile(requestOptions, downloadLocation);
89+
}

src/util/vscodePrompts.ts

+1-10
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,8 @@ export async function askForArtifactID(): Promise<string | undefined> {
4141
}
4242

4343
export async function askForJavaSEVersion(
44-
mpVersion: string,
45-
mpServer: string
44+
supportedJavaSEVersions: string[]
4645
): Promise<string | undefined> {
47-
const MP32_JAVA_11_SUPPORTED = ["LIBERTY", "PAYARA_MICRO", "HELIDON", "THORNTAIL_V2", "WILDFLY"];
48-
49-
let supportedJavaSEVersions = ["SE8"];
50-
51-
if (mpVersion === "MP32" && MP32_JAVA_11_SUPPORTED.includes(mpServer)) {
52-
supportedJavaSEVersions = ["SE8", "SE11"];
53-
}
54-
5546
return await vscode.window.showQuickPick(supportedJavaSEVersions, {
5647
ignoreFocusOut: true,
5748
placeHolder: "Select a Java SE version.",

0 commit comments

Comments
 (0)