[feat]: [AH-152]: get files maven api (#3329)

* [AH-152]: get files maven api
* [AH-152]: get files maven api
* [AH-152]: get files maven api
* [feat]: [AH-152]: support get artifact files for maven
* [feat]: [AH-152]: support get artifact files for maven
pull/3616/head
Pragyesh Mishra 2025-01-27 17:22:49 +00:00 committed by Harness
parent e36647c78d
commit 7e777093a4
10 changed files with 84 additions and 32 deletions

View File

@ -190,12 +190,13 @@ func GetAllArtifactFilesResponse(
registryURL string,
artifactName string,
version string,
packageType artifactapi.PackageType,
) *artifactapi.FileDetailResponseJSONResponse {
var fileMetadataList []artifactapi.FileDetail
if files == nil {
fileMetadataList = make([]artifactapi.FileDetail, 0)
} else {
fileMetadataList = GetArtifactFilesMetadata(files, registryURL, artifactName, version)
fileMetadataList = GetArtifactFilesMetadata(files, registryURL, artifactName, version, packageType)
}
pageCount := GetPageCount(count, pageSize)
return &artifactapi.FileDetailResponseJSONResponse{
@ -208,18 +209,32 @@ func GetAllArtifactFilesResponse(
}
}
func GetArtifactFilesMetadata(metadata *[]types.FileNodeMetadata, registryURL string,
artifactName string, version string) []artifactapi.FileDetail {
func GetArtifactFilesMetadata(metadata *[]types.FileNodeMetadata,
registryURL string,
artifactName string,
version string,
packageType artifactapi.PackageType,
) []artifactapi.FileDetail {
var files []artifactapi.FileDetail
for _, file := range *metadata {
filePathPrefix := "/" + artifactName + "/" + version + "/"
filename := strings.Replace(file.Path, filePathPrefix, "", 1)
var downloadCommand string
if artifactapi.PackageTypeGENERIC == packageType {
downloadCommand = GetGenericArtifactFileDownloadCommand(registryURL, artifactName, version, filename)
} else if artifactapi.PackageTypeMAVEN == packageType {
artifactName = strings.ReplaceAll(artifactName, ".", "/")
artifactName = strings.ReplaceAll(artifactName, ":", "/")
filePathPrefix = "/" + artifactName + "/" + version + "/"
filename = strings.Replace(file.Path, filePathPrefix, "", 1)
downloadCommand = GetMavenArtifactFileDownloadCommand(registryURL, artifactName, version, filename)
}
files = append(files, artifactapi.FileDetail{
Checksums: getCheckSums(file),
Size: GetSize(file.Size),
CreatedAt: fmt.Sprint(file.CreatedAt),
Name: filename,
DownloadCommand: GetGenericArtifactFileDownloadCommand(registryURL, artifactName, version, filename),
DownloadCommand: downloadCommand,
})
}
return files

View File

@ -96,9 +96,15 @@ func (c *APIController) GetArtifactFiles(
}, nil
}
registryURL := c.URLProvider.RegistryURL(ctx, reqInfo.RootIdentifier,
strings.ToLower(string(registry.PackageType)), reqInfo.RegistryIdentifier)
registryURL := c.URLProvider.RegistryURL(ctx,
reqInfo.RootIdentifier, strings.ToLower(string(registry.PackageType)), reqInfo.RegistryIdentifier)
filePathPrefix := "/" + img.Name + "/" + art.Version + "%"
if artifact.PackageTypeMAVEN == registry.PackageType {
artifactName := strings.ReplaceAll(img.Name, ".", "/")
artifactName = strings.ReplaceAll(artifactName, ":", "/")
filePathPrefix = "/" + artifactName + "/" + art.Version + "%"
}
fileMetadataList, err := c.fileManager.GetFilesMetadata(ctx, filePathPrefix, img.RegistryID,
reqInfo.sortByField, reqInfo.sortByOrder, reqInfo.limit, reqInfo.offset, reqInfo.searchTerm)
@ -126,10 +132,11 @@ func (c *APIController) GetArtifactFiles(
//nolint:exhaustive
switch registry.PackageType {
case artifact.PackageTypeGENERIC:
case artifact.PackageTypeGENERIC, artifact.PackageTypeMAVEN:
return artifact.GetArtifactFiles200JSONResponse{
FileDetailResponseJSONResponse: *GetAllArtifactFilesResponse(
fileMetadataList, count, reqInfo.pageNumber, reqInfo.limit, registryURL, img.Name, art.Version),
fileMetadataList, count, reqInfo.pageNumber, reqInfo.limit, registryURL, img.Name, art.Version,
registry.PackageType),
}, nil
default:
return artifact.GetArtifactFiles400JSONResponse{

View File

@ -402,6 +402,25 @@ func GetGenericArtifactFileDownloadCommand(regURL, artifact, version, filename s
return downloadCommand
}
func GetMavenArtifactFileDownloadCommand(regURL, artifact, version, filename string) string {
downloadCommand := "curl --location '<HOSTNAME>/<ARTIFACT>/<VERSION>/<FILENAME>'" +
" --header 'Authorization: <IDENTITY_TOKEN>'"
// Replace the placeholders with the actual values
replacements := map[string]string{
"<HOSTNAME>": regURL,
"<ARTIFACT>": artifact,
"<VERSION>": version,
"<FILENAME>": filename,
}
for placeholder, value := range replacements {
downloadCommand = strings.ReplaceAll(downloadCommand, placeholder, value)
}
return downloadCommand
}
// CleanURLPath removes leading and trailing spaces and trailing slashes from the given URL string.
func CleanURLPath(input *string) {
if input == nil {

View File

@ -4768,8 +4768,8 @@ type StrictServerInterface interface {
GetAllRegistries(ctx context.Context, request GetAllRegistriesRequestObject) (GetAllRegistriesResponseObject, error)
}
type StrictHandlerFunc = strictnethttp.StrictHttpHandlerFunc
type StrictMiddlewareFunc = strictnethttp.StrictHttpMiddlewareFunc
type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc
type StrictMiddlewareFunc = strictnethttp.StrictHTTPMiddlewareFunc
type StrictHTTPServerOptions struct {
RequestErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)

View File

@ -135,8 +135,9 @@ func (c *Controller) GetArtifact(ctx context.Context, info pkg.MavenArtifactInfo
f := func(registry registrytypes.Registry, a Artifact) Response {
info.SetMavenRepoKey(registry.Name)
info.RegistryID = registry.ID
headers, body, fileReader, e := a.(Registry).GetArtifact(ctx, info)
return &GetArtifactResponse{e, headers, "", body, fileReader}
headers, body, fileReader, redirectURL, e := a.(Registry).GetArtifact(ctx, info)
return &GetArtifactResponse{e, headers, redirectURL,
body, fileReader}
}
return c.ProxyWrapper(ctx, f, info)
}

View File

@ -58,17 +58,22 @@ func (r *LocalRegistry) GetMavenArtifactType() string {
func (r *LocalRegistry) HeadArtifact(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
responseHeaders, _, _, errs = r.FetchArtifact(ctx, info, false)
responseHeaders, _, _, _, errs = r.FetchArtifact(ctx, info, false)
return responseHeaders, errs
}
func (r *LocalRegistry) GetArtifact(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error) {
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser,
redirectURL string, errs []error) {
return r.FetchArtifact(ctx, info, true)
}
func (r *LocalRegistry) FetchArtifact(ctx context.Context, info pkg.MavenArtifactInfo, serveFile bool) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error) {
responseHeaders *commons.ResponseHeaders,
body *storage.FileReader,
readCloser io.ReadCloser,
redirectURL string,
errs []error) {
filePath := utils.GetFilePath(info)
name := info.GroupID + ":" + info.ArtifactID
dbImage, err2 := r.DBStore.ImageDao.GetByName(ctx, info.RegistryID, name)
@ -94,7 +99,7 @@ func (r *LocalRegistry) FetchArtifact(ctx context.Context, info pkg.MavenArtifac
}
var fileReader *storage.FileReader
if serveFile {
fileReader, _, _, err = r.fileManager.DownloadFile(ctx, filePath, types.Registry{
fileReader, _, redirectURL, err = r.fileManager.DownloadFile(ctx, filePath, types.Registry{
ID: info.RegistryID,
Name: info.RootIdentifier,
}, info.RootIdentifier)
@ -103,7 +108,7 @@ func (r *LocalRegistry) FetchArtifact(ctx context.Context, info pkg.MavenArtifac
}
}
responseHeaders = utils.SetHeaders(info, fileInfo)
return responseHeaders, fileReader, nil, nil
return responseHeaders, fileReader, nil, redirectURL, nil
}
func (r *LocalRegistry) PutArtifact(ctx context.Context, info pkg.MavenArtifactInfo, fileReader io.Reader) (
@ -156,11 +161,12 @@ func (r *LocalRegistry) PutArtifact(ctx context.Context, info pkg.MavenArtifactI
}
func processError(err error) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error) {
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser,
redirectURL string, errs []error) {
if strings.Contains(err.Error(), sql.ErrNoRows.Error()) ||
strings.Contains(err.Error(), "resource not found") ||
strings.Contains(err.Error(), "http status code: 404") {
return responseHeaders, nil, nil, []error{commons.NotFoundError(err.Error(), err)}
return responseHeaders, nil, nil, "", []error{commons.NotFoundError(err.Error(), err)}
}
return responseHeaders, nil, nil, []error{errcode.ErrCodeUnknown.WithDetail(err)}
return responseHeaders, nil, nil, "", []error{errcode.ErrCodeUnknown.WithDetail(err)}
}

View File

@ -30,7 +30,8 @@ type Registry interface {
responseHeaders *commons.ResponseHeaders, errs []error)
GetArtifact(ctx context.Context, artInfo pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error)
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser,
redirectURL string, errs []error)
PutArtifact(ctx context.Context, artInfo pkg.MavenArtifactInfo, fileReader io.Reader) (
responseHeaders *commons.ResponseHeaders, errs []error)

View File

@ -55,12 +55,13 @@ func (r *RemoteRegistry) GetMavenArtifactType() string {
func (r *RemoteRegistry) HeadArtifact(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, errs []error) {
responseHeaders, _, _, errs = r.FetchArtifact(ctx, info, false)
responseHeaders, _, _, _, errs = r.FetchArtifact(ctx, info, false)
return responseHeaders, errs
}
func (r *RemoteRegistry) GetArtifact(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error) {
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser,
redirectURL string, errs []error) {
return r.FetchArtifact(ctx, info, true)
}
@ -70,12 +71,13 @@ func (r *RemoteRegistry) PutArtifact(_ context.Context, _ pkg.MavenArtifactInfo,
}
func (r *RemoteRegistry) FetchArtifact(ctx context.Context, info pkg.MavenArtifactInfo, serveFile bool) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser, errs []error) {
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, readCloser io.ReadCloser,
redirectURL string, errs []error) {
log.Ctx(ctx).Info().Msgf("Maven Proxy: %s", info.RegIdentifier)
responseHeaders, body, useLocal := r.proxyController.UseLocalFile(ctx, info)
responseHeaders, body, redirectURL, useLocal := r.proxyController.UseLocalFile(ctx, info)
if useLocal {
return responseHeaders, body, readCloser, errs
return responseHeaders, body, readCloser, redirectURL, errs
}
upstreamProxy, err := r.DBStore.UpstreamProxyDao.GetByRegistryIdentifier(ctx, info.ParentID, info.RegIdentifier)
@ -88,5 +90,5 @@ func (r *RemoteRegistry) FetchArtifact(ctx context.Context, info pkg.MavenArtifa
if err != nil {
return processError(err)
}
return responseHeaders, nil, readCloser, errs
return responseHeaders, nil, readCloser, "", errs
}

View File

@ -39,7 +39,7 @@ type controller struct {
type Controller interface {
UseLocalFile(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, fileReader *storage.FileReader, useLocal bool)
responseHeaders *commons.ResponseHeaders, fileReader *storage.FileReader, redirectURL string, useLocal bool)
ProxyFile(
ctx context.Context, info pkg.MavenArtifactInfo, proxy types.UpstreamProxy, serveFile bool,
@ -59,9 +59,9 @@ func NewProxyController(
}
func (c *controller) UseLocalFile(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, fileReader *storage.FileReader, useLocal bool) {
responseHeaders, body, _, e := c.localRegistry.GetArtifact(ctx, info)
return responseHeaders, body, len(e) == 0
responseHeaders *commons.ResponseHeaders, fileReader *storage.FileReader, redirectURL string, useLocal bool) {
responseHeaders, body, _, redirectURL, e := c.localRegistry.GetArtifact(ctx, info)
return responseHeaders, body, redirectURL, len(e) == 0
}
func (c *controller) ProxyFile(

View File

@ -28,7 +28,8 @@ type registryInterface interface {
responseHeaders *commons.ResponseHeaders, errs []error)
GetArtifact(ctx context.Context, info pkg.MavenArtifactInfo) (
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, fileReader io.ReadCloser, errs []error)
responseHeaders *commons.ResponseHeaders, body *storage.FileReader, fileReader io.ReadCloser,
redirectURL string, errs []error)
PutArtifact(ctx context.Context, info pkg.MavenArtifactInfo, fileReader io.Reader) (
responseHeaders *commons.ResponseHeaders, errs []error)