Skip to content

Commit

Permalink
Merge pull request #43663 from ballerina-platform/2201.11.0-stage
Browse files Browse the repository at this point in the history
Sync `2201.11.x` with 2201.11.0 stage
  • Loading branch information
keizer619 authored Nov 29, 2024
2 parents c4c87cb + fcbcfda commit 8aebaaa
Show file tree
Hide file tree
Showing 87 changed files with 24,788 additions and 398 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull_request_windows_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
windows_build:
name: Build with some tests on Windows
runs-on: windows-latest
timeout-minutes: 240
timeout-minutes: 300
concurrency:
group: ${{ github.head_ref }}-windows
cancel-in-progress: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ public void setTypeForcefully(Type type) {

protected void populateInitialValues(BMapInitialValueEntry[] initialValues) {
Map<String, BFunctionPointer> defaultValues = new HashMap<>();
if (type.getTag() == TypeTags.RECORD_TYPE_TAG) {
defaultValues.putAll(((BRecordType) type).getDefaultValues());
if (referredType.getTag() == TypeTags.RECORD_TYPE_TAG) {
defaultValues.putAll(((BRecordType) referredType).getDefaultValues());
}

for (BMapInitialValueEntry initialValue : initialValues) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,21 @@
import org.ballerinalang.central.client.model.ToolResolutionCentralResponse;
import org.ballerinalang.central.client.model.ToolSearchResult;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Proxy;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -64,6 +74,9 @@
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
Expand Down Expand Up @@ -143,14 +156,16 @@ public class CentralAPIClient {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final MediaType JSON_CONTENT_TYPE = MediaType.parse("application/json");

// System property name for enabling central verbose
public static final String SYS_PROP_CENTRAL_VERBOSE_ENABLED = "CENTRAL_VERBOSE_ENABLED";
private static final int DEFAULT_CONNECT_TIMEOUT = 60;
private static final int DEFAULT_READ_TIMEOUT = 60;
private static final int DEFAULT_WRITE_TIMEOUT = 60;
private static final int DEFAULT_CALL_TIMEOUT = 0;
private static final int MAX_RETRY = 1;
public static final String CONNECTION_RESET = "Connection reset";
private static final String ENV_CENTRAL_VERBOSE_ENABLED = "CENTRAL_VERBOSE_ENABLED";
private static final String ENV_TRUSTSTORE_PATH = "BALLERINA_CA_BUNDLE";
private static final String ENV_TRUSTSTORE_PASSWORD = "BALLERINA_CA_PASSWORD";
private static final String ENV_CERT_PATH = "BALLERINA_CA_CERT";

private final String baseUrl;
private final Proxy proxy;
Expand All @@ -164,20 +179,26 @@ public class CentralAPIClient {
private final int writeTimeout;
private final int callTimeout;
private final int maxRetries;
private final String trustStorePath;
private final String trustStorePassword;
private final String singleCertPath;

public CentralAPIClient(String baseUrl, Proxy proxy, String accessToken) {
this.outStream = System.out;
this.baseUrl = baseUrl;
this.proxy = proxy;
this.accessToken = accessToken;
this.verboseEnabled = Boolean.parseBoolean(System.getenv(SYS_PROP_CENTRAL_VERBOSE_ENABLED));
this.verboseEnabled = Boolean.parseBoolean(System.getenv(ENV_CENTRAL_VERBOSE_ENABLED));
this.proxyUsername = "";
this.proxyPassword = "";
this.connectTimeout = DEFAULT_CONNECT_TIMEOUT;
this.readTimeout = DEFAULT_READ_TIMEOUT;
this.writeTimeout = DEFAULT_WRITE_TIMEOUT;
this.callTimeout = DEFAULT_CALL_TIMEOUT;
this.maxRetries = MAX_RETRY;
this.trustStorePath = System.getenv(ENV_TRUSTSTORE_PATH);
this.trustStorePassword = System.getenv(ENV_TRUSTSTORE_PASSWORD);
this.singleCertPath = System.getenv(ENV_CERT_PATH);
}

public CentralAPIClient(String baseUrl, Proxy proxy, String accessToken, boolean verboseEnabled, int maxRetries,
Expand All @@ -194,6 +215,9 @@ public CentralAPIClient(String baseUrl, Proxy proxy, String accessToken, boolean
this.writeTimeout = DEFAULT_WRITE_TIMEOUT;
this.callTimeout = DEFAULT_CALL_TIMEOUT;
this.maxRetries = maxRetries;
this.trustStorePath = System.getenv(ENV_TRUSTSTORE_PATH);
this.trustStorePassword = System.getenv(ENV_TRUSTSTORE_PASSWORD);
this.singleCertPath = System.getenv(ENV_CERT_PATH);
}

public CentralAPIClient(String baseUrl, Proxy proxy, String proxyUsername, String proxyPassword,
Expand All @@ -203,14 +227,17 @@ public CentralAPIClient(String baseUrl, Proxy proxy, String proxyUsername, Strin
this.baseUrl = baseUrl;
this.proxy = proxy;
this.accessToken = accessToken;
this.verboseEnabled = Boolean.parseBoolean(System.getenv(SYS_PROP_CENTRAL_VERBOSE_ENABLED));
this.verboseEnabled = Boolean.parseBoolean(System.getenv(ENV_CENTRAL_VERBOSE_ENABLED));
this.proxyUsername = proxyUsername;
this.proxyPassword = proxyPassword;
this.connectTimeout = connectionTimeout;
this.readTimeout = readTimeout;
this.writeTimeout = writeTimeout;
this.callTimeout = callTimeout;
this.maxRetries = maxRetries;
this.trustStorePath = System.getenv(ENV_TRUSTSTORE_PATH);
this.trustStorePassword = System.getenv(ENV_TRUSTSTORE_PASSWORD);
this.singleCertPath = System.getenv(ENV_CERT_PATH);
}

/**
Expand Down Expand Up @@ -1579,17 +1606,58 @@ public JsonObject getConnector(ConnectorInfo connector, String supportedPlatform
*
* @return the client
*/
protected OkHttpClient getClient() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
protected OkHttpClient getClient() throws CentralClientException {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.callTimeout(callTimeout, TimeUnit.SECONDS)
.followRedirects(false)
.retryOnConnectionFailure(true)
.proxy(this.proxy)
.addInterceptor(new CustomRetryInterceptor(this.maxRetries))
.build();
.addInterceptor(new CustomRetryInterceptor(this.maxRetries));

// Load custom truststore if provided, otherwise use the default truststore
try {
KeyStore truststore;
if (this.trustStorePath != null && this.trustStorePassword != null) {
truststore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream keys = new FileInputStream(trustStorePath)) {
truststore.load(keys, trustStorePassword.toCharArray());
}
} else {
truststore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream defaultKeys = new FileInputStream(System.getProperty("java.home") +
"/lib/security/cacerts")) {
truststore.load(defaultKeys, "changeit".toCharArray()); // Default password for cacerts
}
}

// If there's a single certificate to add
if (this.singleCertPath != null) {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
try (InputStream certInputStream = new FileInputStream(singleCertPath)) {
Certificate certificate = certificateFactory.generateCertificate(certInputStream);
truststore.setCertificateEntry("bal-cert", certificate);
}
}

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(truststore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
SSLContext.setDefault(sslContext);

builder.sslSocketFactory(sslContext.getSocketFactory(),
(X509TrustManager) trustManagerFactory.getTrustManagers()[0]);
} catch (CertificateException | KeyStoreException | IOException | NoSuchAlgorithmException |
KeyManagementException e) {
throw new CentralClientException(e.getMessage());
}

OkHttpClient okHttpClient = builder.build();

if ((!(this.proxyUsername).isEmpty() && !(this.proxyPassword).isEmpty())) {
Authenticator proxyAuthenticator = (route, response) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import okhttp3.Response;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.ballerinalang.central.client.exceptions.CentralClientException;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
Expand All @@ -49,7 +50,7 @@ public class TestCustomRetryInterceptor {


@BeforeClass
public void setUp() {
public void setUp() throws CentralClientException {
this.console = new ByteArrayOutputStream();
PrintStream outStream = new PrintStream(this.console);
CentralAPIClient centralAPIClient = new CentralAPIClient("https://localhost:9090/registry",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
*/
public class BalaProject extends Project {
private final String platform;
private final String balaVersion;

/**
* Loads a BalaProject from the provided bala path.
Expand All @@ -70,6 +71,7 @@ public static BalaProject loadProject(ProjectEnvironmentBuilder environmentBuild
private BalaProject(ProjectEnvironmentBuilder environmentBuilder, Path balaPath, BuildOptions buildOptions) {
super(ProjectKind.BALA_PROJECT, balaPath, environmentBuilder, buildOptions);
this.platform = BalaFiles.readPackageJson(balaPath).getPlatform();
this.balaVersion = BalaFiles.readBalaJson(balaPath).getBala_version();
}

@Override
Expand Down Expand Up @@ -136,6 +138,10 @@ public String platform() {
return platform;
}

public String balaVersion() {
return balaVersion;
}

private boolean isFilePathInProject(Path filepath) {
try {
ProjectPaths.packageRoot(filepath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.ballerina.projects.PlatformLibraryScope;
import io.ballerina.projects.ProjectException;
import io.ballerina.projects.internal.bala.BalToolJson;
import io.ballerina.projects.internal.bala.BalaJson;
import io.ballerina.projects.internal.bala.CompilerPluginJson;
import io.ballerina.projects.internal.bala.DependencyGraphJson;
import io.ballerina.projects.internal.bala.ModuleDependency;
Expand Down Expand Up @@ -66,6 +67,7 @@
import static io.ballerina.projects.internal.ProjectFiles.loadDocuments;
import static io.ballerina.projects.internal.ProjectFiles.loadResources;
import static io.ballerina.projects.util.ProjectConstants.BALA_DOCS_DIR;
import static io.ballerina.projects.util.ProjectConstants.BALA_JSON;
import static io.ballerina.projects.util.ProjectConstants.BAL_TOOL_JSON;
import static io.ballerina.projects.util.ProjectConstants.COMPILER_PLUGIN_DIR;
import static io.ballerina.projects.util.ProjectConstants.COMPILER_PLUGIN_JSON;
Expand Down Expand Up @@ -756,6 +758,41 @@ public static PackageJson readPackageJson(Path balaPath) {
return packageJson;
}

public static BalaJson readBalaJson(Path balaPath) {
BalaJson balaJson;
if (balaPath.toFile().isDirectory()) {
Path balaJsonPath = balaPath.resolve(BALA_JSON);
if (Files.notExists(balaJsonPath)) {
throw new ProjectException("bala.json does not exists in '" + balaPath + "'");
}
try (BufferedReader bufferedReader = Files.newBufferedReader(balaJsonPath)) {
balaJson = gson.fromJson(bufferedReader, BalaJson.class);
} catch (JsonSyntaxException e) {
throw new ProjectException("Invalid bala.json format in '" + balaPath + "'");
} catch (IOException e) {
throw new ProjectException("Failed to read the bala.json in '" + balaPath + "'");
}
} else {
URI zipURI = getZipURI(balaPath);
try (FileSystem zipFileSystem = FileSystems.newFileSystem(zipURI, new HashMap<>())) {
Path balaJsonPath = zipFileSystem.getPath(BALA_JSON);
if (Files.notExists(balaJsonPath)) {
throw new ProjectException("package.json does not exists in '" + balaPath + "'");
}
try (BufferedReader bufferedReader = Files.newBufferedReader(balaJsonPath)) {
balaJson = gson.fromJson(bufferedReader, BalaJson.class);
} catch (JsonSyntaxException e) {
throw new ProjectException("Invalid package.json format in '" + balaPath + "'");
} catch (IOException e) {
throw new ProjectException("Failed to read the package.json in '" + balaPath + "'");
}
} catch (IOException e) {
throw new ProjectException("Failed to read bala file:" + balaPath);
}
}
return balaJson;
}

private static URI getZipURI(Path balaPath) {
return URI.create("jar:" + balaPath.toAbsolutePath().toUri());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ public class ManifestBuilder {
private static final String TARGETMODULE = "targetModule";
private static final String OPTIONS = "options";
private static final String TOOL = "tool";

private static final String DESCRIPTION = "description";
private static final String README = "readme";

Expand Down Expand Up @@ -235,16 +234,25 @@ private PackageManifest parseAsPackageManifest() {
description = getStringValueFromTomlTableNode(pkgNode, DESCRIPTION, "");
moduleEntries = getModuleEntries(pkgNode, customReadmeVal, packageDescriptor.name());

if (!exported.isEmpty()) {
reportDiagnostic(pkgNode.entries().get(EXPORT),
"'export' under [package] is deprecated. " +
"Add the exports using the 'export' field under '[[package.modules]]'",
ProjectDiagnosticErrorCode.DEPRECATED_BALLERINA_TOML_ENTRY, DiagnosticSeverity.WARNING);
}
if (!isOldStructure) {
if (!exported.isEmpty()) {
reportDiagnostic(pkgNode.entries().get(EXPORT),
"'export' under [package] is deprecated. " +
"Add the exports using the 'export' field under '[[package.modules]]'",
ProjectDiagnosticErrorCode.DEPRECATED_BALLERINA_TOML_ENTRY, DiagnosticSeverity.WARNING);
if (!exported.contains(packageDescriptor.name().toString())) {
exported.add(packageDescriptor.name().toString()); // default module is always exported
}
for (PackageManifest.Module moduleEntry : moduleEntries) {
if (!moduleEntry.export()) {
continue;
}
String name = moduleEntry.name();
if (!exported.contains(name)) {
exported.add(name);
}
}
exported.add(packageDescriptor.name().toString()); // default module is always exported
exported.addAll(moduleEntries.stream().filter(
PackageManifest.Module::export).map(PackageManifest.Module::name).toList());
}
}
}
Expand Down Expand Up @@ -346,15 +354,18 @@ private List<PackageManifest.Module> getModuleEntries(
TomlTableArrayNode dependencyTableArray = (TomlTableArrayNode) dependencyEntries;
for (TomlTableNode modulesNode : dependencyTableArray.children()) {
String moduleName = getStringValueFromTomlTableNode(modulesNode, NAME, null);
if (moduleName == null) {
if (moduleName == null
|| !moduleName.contains(DOT)) { // The invalid module name is already handled
continue;
}
String moduleNamepart = moduleName.substring(packageName.toString().length() + 1);

boolean export = Boolean.TRUE.equals(getBooleanValueFromTomlTableNode(modulesNode, EXPORT));
String description = getStringValueFromTomlTableNode(modulesNode, DESCRIPTION, null);
String modReadme = getStringValueFromTomlTableNode(modulesNode, README, null);
if (modReadme == null) {
Path defaultReadme = modulesRoot.resolve(moduleName).resolve(ProjectConstants.README_MD_FILE_NAME);
Path defaultReadme = modulesRoot.resolve(moduleNamepart)
.resolve(ProjectConstants.README_MD_FILE_NAME);
if (Files.exists(defaultReadme)) {
modReadme = defaultReadme.toString();
}
Expand All @@ -366,7 +377,7 @@ private List<PackageManifest.Module> getModuleEntries(
PackageManifest.Module module = new PackageManifest.Module(moduleName, export,
description, modReadme);
moduleList.add(module);
moduleDirs.remove(moduleName.split("[.]")[1]);
moduleDirs.remove(moduleNamepart);
}
// If there are README.mds in other modules, add them
for (Map.Entry<String, Path> pathEntry : moduleDirs.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4881,7 +4881,7 @@ private BAttachedFunction createResourceFunction(BLangFunction funcNode, BInvoka
List<BResourcePathSegmentSymbol> pathSegmentSymbols = new ArrayList<>(resourcePathCount);
BResourcePathSegmentSymbol parentResource = null;
for (BLangResourcePathSegment pathSegment : pathSegments) {
Name resourcePathSymbolName = Names.fromString(pathSegment.name.value);
Name resourcePathSymbolName = Names.fromString(pathSegment.name.originalValue);
BType resourcePathSegmentType = pathSegment.typeNode == null ?
symTable.noType : symResolver.resolveTypeNode(pathSegment.typeNode, env);
pathSegment.setBType(resourcePathSegmentType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public NodeList<StatementNode> statements() {
return new NodeList<>(childInBucket(1));
}

public NodeAndCommentList<Node> statementsWithComments() {
return new NodeAndCommentList<>(childInBucket(1), childInBucket(2));
}

public Token closeBraceToken() {
return childInBucket(2);
}
Expand Down
Loading

0 comments on commit 8aebaaa

Please sign in to comment.