Artifactory 是一个非常好用的私服产品,有两个分支:
一个是开源的OOS(From version 4.8.1, Artifactory OSS is licensed under AGPL 3.0 (previously LGPL 3.0))
一个是需要付费的PRO,10几万,贵的有点离谱,但功能也更丰富。
这里主要是改造开源的那个版本,你可以从他们的网站下载到源代码,然后自己编译调试。
文件的属性,只有PRO版本才会有,但是我们自己写点代码这个可以有。还有就是Rest API,也是只有PRO才会提供,但是我们也可以在不改变原有程序的情况下,添加一个我们自己写的一个类,实现我们需要的API,这个也可以有。
我这里以3.5.3版本为例,描述下:
添加属性的方法,按照下面方法,即可以把属性显示出来 package org.artifactory.addon.wicket;
private static class DisabledPropertiesPanel extends PropertiesPanel {
public DisabledPropertiesPanel(String id, String nestedPanelId) {
super(id);
//add(new DisabledCollapsibleBehavior()); <-- 注释掉这行即可以把属性展示出来
add(new WebMarkupContainer(nestedPanelId));
}
@Override
protected Component newToolbar(String id) {
return new DisabledAddonHelpBubble(id, PROPERTIES);
}
}
添加自定义的API的方式更简单,只需把我们实现的API放到 package org.artifactory.rest.resource.* 下,我的是放到 package org.artifactory.rest.resource.versions; 下了。
package org.artifactory.rest.resource.versions;
import org.artifactory.api.config.CentralConfigService;
import org.artifactory.api.module.ModuleInfo;
import org.artifactory.api.repo.RepositoryService;
import org.artifactory.api.security.AuthorizationService;
import org.artifactory.fs.ItemInfo;
import org.artifactory.fs.StatsInfo;
import org.artifactory.md.Properties;
import org.artifactory.model.common.RepoPathImpl;
import org.artifactory.model.xstream.fs.PropertiesImpl;
import org.artifactory.repo.RepoPath;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
/**
* Created by Nelson on 2016-12-06.
* VersionMaintenanceResources
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Path(VersionMaintenanceResources.PATH_ROOT)
@RolesAllowed({AuthorizationService.ROLE_USER, AuthorizationService.ROLE_ADMIN})
public class VersionMaintenanceResources {
private static final Logger logger = LoggerFactory.getLogger(VersionMaintenanceResources.class);
public static final String PATH_ROOT = "version-maintenance";
@Context
private HttpServletRequest request;
@Autowired
private RepositoryService repoService;
@Autowired
private CentralConfigService centralConfig;
@Autowired
private AuthorizationService authorizationService;
@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("property/get/{repoKey: (?!_any)[^/]+}/{path: (?!_any).+}")
public Response getRepoPropertiesByPath(@PathParam("repoKey") String repoKey, @PathParam("path") String path) {
Response response = hasPermission();
if (null != response) {
return response;
}
RepoPath repoPath = new RepoPathImpl(repoKey, path);
if (repoService.exists(repoPath)) {
Properties properties = repoService.getProperties(repoPath);
Map<String, String> result = new HashMap<>();
if (null != properties) {
for (String key : properties.keySet()) {
Set<String> strings = properties.get(key);
if (null != strings) {
result.put(key, strings.toString());
}
}
}
return Response.ok(result, MediaType.APPLICATION_JSON_TYPE).build();
}
return Response.status(Response.Status.BAD_REQUEST)
.entity("Repo path not exists")
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
}
@PUT
@Produces({MediaType.APPLICATION_JSON})
@Path("property/set/{repoKey: (?!_any)[^/]+}/{path: (?!_any).+}")
public Response setRepoPropertiesByPath(@PathParam("repoKey") String repoKey, @PathParam("path") String path) {
Response response = hasPermission();
if (null != response) {
return response;
}
RepoPath repoPath = new RepoPathImpl(repoKey, path);
if (repoService.exists(repoPath)) {
Properties properties = repoService.getProperties(repoPath);
if (null == properties) {
properties = new PropertiesImpl();
}
Map<String, String[]> parameterMap = request.getParameterMap();
if ((null == parameterMap) || parameterMap.isEmpty()) {
properties.clear();
}
if (null != parameterMap) {
for (String propName : parameterMap.keySet()) {
if (properties.containsKey(propName)) {
properties.removeAll(propName);
}
String[] values = parameterMap.get(propName);
if (null != values) {
for (String value : values) {
if ((null != value) && (value.trim().length() > 0)) {
properties.put(propName, value);
}
}
}
}
repoService.setProperties(repoPath, properties);
return Response.ok("Success", MediaType.APPLICATION_JSON_TYPE).build();
}
}
return Response.status(Response.Status.BAD_REQUEST)
.entity("Repo path not exists")
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
}
@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("list/{repoKey: (?!_any)[^/]+}/{path: (?!_any).+|$}")
public Response getChildRepoByPath(@PathParam("repoKey") String repoKey, @PathParam("path") String path) {
Response response = hasPermission();
if (null != response) {
return response;
}
List<FileInfo> fileInfoList = new ArrayList<>();
RepoPath repoPath = new RepoPathImpl(repoKey, path);
if (repoService.exists(repoPath)) {
ItemInfo itemInfo = repoService.getItemInfo(repoPath);
if (itemInfo.isFolder()) {
List<ItemInfo> itemInfoList = repoService.getChildren(repoPath);
for (ItemInfo info : itemInfoList) {
fileInfoList.add(createFileInfo(info.getRepoPath()));
}
} else {
fileInfoList.add(createFileInfo(itemInfo.getRepoPath()));
}
return Response.ok()
.entity(fileInfoList)
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
} else {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Repo path not exists")
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
}
}
@DELETE
@Produces({MediaType.APPLICATION_JSON})
@Path("remove/{repoKey: (?!_any)[^/]+}/{path: (?!_any).+}")
public Response removeRepoByPath(@PathParam("repoKey") String repoKey, @PathParam("path") String path) {
Response response = hasPermission();
if (null != response) {
return response;
}
WrongPath result = new WrongPath();
Map<String, String[]> parameterMap = request.getParameterMap();
if ((null != parameterMap) && (parameterMap.size() > 0)) {
if (parameterMap.containsKey("versions")) {
String[] versions = parameterMap.get("versions");
for (String ver : versions) {
RepoPath repoPath;
if (path.endsWith("/")) {
repoPath = new RepoPathImpl(repoKey, path + ver);
} else {
repoPath = new RepoPathImpl(repoKey, path + "/" + ver);
}
if (repoService.exists(repoPath)) {
repoService.undeploy(repoPath);
} else {
result.add(repoPath.toString());
}
}
}
} else {
RepoPath repoPath = new RepoPathImpl(repoKey, path);
if (repoService.exists(repoPath)) {
repoService.undeploy(repoPath);
} else {
result.add(repoPath.toString());
}
}
if (result.size() > 0) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(result)
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
} else {
return Response.ok("Success", MediaType.APPLICATION_JSON_TYPE).build();
}
}
private Response hasPermission() {
if (authorizationService.isAuthenticated() && !authorizationService.isAnonymous()) {
return null;
} else {
if (centralConfig.getDescriptor().getSecurity().isHideUnauthorizedResources()) {
return Response.status(Response.Status.NOT_FOUND).build();
}
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private FileInfo createFileInfo(RepoPath repoPath) {
FileInfo fileInfo = new FileInfo();
fileInfo.setFolder(repoPath.isFolder());
fileInfo.setRepoKey(repoPath.getRepoKey());
fileInfo.setPath(repoPath.getPath());
ItemInfo itemInfo = null;
if (repoPath.isFile()) {
org.artifactory.fs.FileInfo file;
file = repoService.getFileInfo(repoPath);
fileInfo.setSize(file.getSize());
fileInfo.setMd5(file.getMd5());
fileInfo.setSha1(file.getSha1());
ModuleInfo moduleInfo = repoService.getItemModuleInfo(repoPath);
fileInfo.setGroupId(moduleInfo.getOrganization());
fileInfo.setArtifactId(moduleInfo.getModule());
fileInfo.setVersion(moduleInfo.getBaseRevision());
fileInfo.setExt(moduleInfo.getExt());
fileInfo.setClassifier(moduleInfo.getClassifier());
itemInfo = file;
}
if (repoPath.isFolder()) {
org.artifactory.fs.FolderInfo file;
file = repoService.getFolderInfo(repoPath);
itemInfo = file;
}
if (null != itemInfo) {
fileInfo.setCreatedBy(itemInfo.getCreatedBy());
fileInfo.setModifiedBy(itemInfo.getModifiedBy());
fileInfo.setCreated(itemInfo.getCreated());
fileInfo.setLastModified(itemInfo.getLastModified());
}
StatsInfo statsInfo = repoService.getStatsInfo(repoPath);
if (null != statsInfo) {
fileInfo.setDownloadCount(statsInfo.getDownloadCount());
fileInfo.setLastDownloaded(statsInfo.getLastDownloaded());
}
if (repoService.hasProperties(repoPath)) {
Properties properties = repoService.getProperties(repoPath);
if (null != properties) {
for (String key : properties.keySet()) {
Set<String> value = properties.get(key);
if (null != value) {
fileInfo.getProperties().put(key, value.toString());
}
}
}
}
return fileInfo;
}
public class FileInfo {
private boolean isFolder;
private String repoKey;
private String path;
private String createdBy;
private long created;
private String modifiedBy;
private long lastModified;
private long size;
private String md5;
private String sha1;
private long downloadCount;
private long lastDownloaded;
private String groupId;
private String artifactId;
private String version;
private String ext;
private String classifier;
private Map<String, String> properties = new HashMap<>();
public long getLastModified() {
return lastModified;
}
public void setLastModified(long lastModified) {
this.lastModified = lastModified;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getRepoKey() {
return repoKey;
}
public void setRepoKey(String repoKey) {
this.repoKey = repoKey;
}
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
public boolean isFolder() {
return isFolder;
}
public void setFolder(boolean folder) {
isFolder = folder;
}
public long getDownloadCount() {
return downloadCount;
}
public void setDownloadCount(long downloadCount) {
this.downloadCount = downloadCount;
}
public long getLastDownloaded() {
return lastDownloaded;
}
public void setLastDownloaded(long lastDownloaded) {
this.lastDownloaded = lastDownloaded;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public String getSha1() {
return sha1;
}
public void setSha1(String sha1) {
this.sha1 = sha1;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getExt() {
return ext;
}
public void setExt(String ext) {
this.ext = ext;
}
public String getClassifier() {
return classifier;
}
public void setClassifier(String classifier) {
this.classifier = classifier;
}
}
public class WrongPath {
private String message = "Repo path not exists";
private List<String> paths = new ArrayList<>();
public List<String> getPaths() {
return paths;
}
public void setPaths(List<String> paths) {
this.paths = paths;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void add(String path) {
paths.add(path);
}
public int size() {
return paths.size();
}
}
}
好了,你可以做自己想做的了