
com.alipay.sofa.koupleless.base.build.plugin.model.CompositeKouplelessAdapterConfig Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alipay.sofa.koupleless.base.build.plugin.model;
import com.alipay.sofa.koupleless.base.build.plugin.KouplelessBaseBuildPrePackageMojo;
import com.alipay.sofa.koupleless.base.build.plugin.common.JarFileUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.model.Dependency;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.resolution.VersionRangeRequest;
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.version.Version;
import org.yaml.snakeyaml.Yaml;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import static com.alipay.sofa.koupleless.base.build.plugin.constant.Constants.ARK_CONF_BASE_DIR;
import static com.alipay.sofa.koupleless.base.build.plugin.constant.Constants.STRING_COLON;
import static com.alipay.sofa.koupleless.base.build.plugin.utils.MavenUtils.getDependencyIdentity;
import static com.google.common.collect.Maps.newHashMap;
/**
* @author [email protected]
* @version $Id: CompositeKouplelessAdapterConfig.java, v 0.1 2024年11月26日 17:47 立蓬 Exp $
*/
public class CompositeKouplelessAdapterConfig implements AdapterConfig {
private static final String CUSTOM_MAPPING_FILE = "adapter-mapping.yaml";
private static final String REMOTE_ADAPTER_CONFIGS = "com.alipay.sofa.koupleless:koupleless-adapter-configs";
/**
* 用户自定义配置:用户配置的 ${baseDir}/adapter-mapping.yaml
*/
private KouplelessAdapterConfig customConfig;
/**
* 远程配置:读取最新的 koupleless-adapter-configs 中的配置
*/
private List remoteConfigs = new ArrayList<>();
public CompositeKouplelessAdapterConfig() {
}
public CompositeKouplelessAdapterConfig(KouplelessBaseBuildPrePackageMojo mojo) {
initCustomConfig(mojo);
initRemoteConfig(mojo);
}
/**
* priority:custom > remote > default
* @return java.util.List
*/
@Override
public List getCommonDependencies() {
Map custom = Maps.newHashMap();
if (null != customConfig) {
custom = toMapWithIdAsKey(customConfig.getCommonDependencies());
}
Map remote = Maps.newHashMap();
for (KouplelessAdapterConfig config : remoteConfigs) {
remote.putAll(toMapWithIdAsKey(config.getCommonDependencies()));
}
// 优先级:custom > remote
Map res = newHashMap();
res.putAll(remote);
res.putAll(custom);
return new ArrayList<>(res.values());
}
private Map toMapWithIdAsKey(List dependencies) {
if (CollectionUtils.isEmpty(dependencies)) {
return Collections.emptyMap();
}
Map res = newHashMap();
dependencies.forEach(d -> {
String key = d.getGroupId() + STRING_COLON + d.getArtifactId();
res.put(key, d);
});
return res;
}
/**
* no priority, all configs are activated
* @param resolvedArtifacts project resolved artifacts
* @return java.util.Map
*/
@Override
public Map matches(Collection resolvedArtifacts) {
Map custom = newHashMap();
if (null != customConfig) {
custom = customConfig.matches(resolvedArtifacts);
}
Map remote = newHashMap();
for (KouplelessAdapterConfig config : remoteConfigs) {
remote.putAll(config.matches(resolvedArtifacts));
}
Map res = newHashMap();
res.putAll(remote);
res.putAll(custom);
return res;
}
@SneakyThrows
protected void initCustomConfig(KouplelessBaseBuildPrePackageMojo mojo) {
File configFile = FileUtils.getFile(mojo.baseDir, ARK_CONF_BASE_DIR, CUSTOM_MAPPING_FILE);
if (!configFile.exists()) {
mojo.getLog().info(String.format(
"koupleless-base-build-plugin: custom-adapter-mapping-config %s not found, will not config it",
configFile.getPath()));
return;
}
InputStream mappingConfigIS = new FileInputStream(configFile);
Yaml yaml = new Yaml();
customConfig = yaml.loadAs(mappingConfigIS, KouplelessAdapterConfig.class);
}
protected void initRemoteConfig(KouplelessBaseBuildPrePackageMojo mojo) {
String kouplelessAdapterConfigVersion = parseRemoteConfigVersion(mojo);
Artifact artifact = downloadAdapterConfigsJar(mojo, kouplelessAdapterConfigVersion);
remoteConfigs = parseConfigs(artifact);
}
private Artifact downloadAdapterConfigsJar(KouplelessBaseBuildPrePackageMojo mojo,
String kouplelessAdapterConfigVersion) {
if (StringUtils.isEmpty(kouplelessAdapterConfigVersion)) {
return null;
}
try {
return mojo.downloadDependency(
parseDependency(REMOTE_ADAPTER_CONFIGS + ":" + kouplelessAdapterConfigVersion));
} catch (Exception e) {
mojo.getLog()
.error("Failed to resolve koupleless-adapter-configs, use default config only.");
throw new RuntimeException(e);
}
}
private List parseConfigs(Artifact artifact) {
if (null == artifact) {
return Collections.emptyList();
}
File file = artifact.getFile();
Map entryToContent = JarFileUtils.getFileContentAsLines(file,
Pattern.compile("(.*\\.yaml)"));
for (Map.Entry entry : entryToContent.entrySet()) {
InputStream inputStream = new ByteArrayInputStream(
ArrayUtils.toPrimitive(entry.getValue()));
Yaml yaml = new Yaml();
KouplelessAdapterConfig config = yaml.loadAs(inputStream,
KouplelessAdapterConfig.class);
remoteConfigs.add(config);
}
return remoteConfigs;
}
private String parseRemoteConfigVersion(KouplelessBaseBuildPrePackageMojo mojo) {
if (StringUtils.isNotEmpty(mojo.kouplelessAdapterConfigVersion)) {
return mojo.kouplelessAdapterConfigVersion;
}
// 从远端获取最新版本
String version = "";
try {
VersionRangeRequest rangeRequest = new VersionRangeRequest()
.setArtifact(new org.eclipse.aether.artifact.DefaultArtifact(
REMOTE_ADAPTER_CONFIGS + ":(,)"))
.setRepositories(mojo.project.getRemoteProjectRepositories());
VersionRangeResult rangeResult = mojo.repositorySystem
.resolveVersionRange(mojo.session.getRepositorySession(), rangeRequest);
Version latestVersion = rangeResult.getHighestVersion();
version = null == latestVersion ? "" : latestVersion.toString();
} catch (VersionRangeResolutionException e) {
mojo.getLog().warn(
"Failed to resolve latest version of koupleless-adapter-configs, use default config only.");
}
return version;
}
private Dependency parseDependency(String dependencyStr) {
String[] dependencyParts = StringUtils.split(dependencyStr, ":");
Preconditions.checkState(dependencyParts.length == 3,
"Invalid dependency format: " + dependencyStr);
Dependency d = new Dependency();
d.setGroupId(dependencyParts[0]);
d.setArtifactId(dependencyParts[1]);
d.setVersion(dependencyParts[2]);
return d;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy