Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/jfrog/jfrog-client-go into i…
Browse files Browse the repository at this point in the history
…mprove-errors
  • Loading branch information
sverdlov93 committed Nov 28, 2024
2 parents 0c529f7 + ecc791f commit 9026fac
Show file tree
Hide file tree
Showing 22 changed files with 462 additions and 210 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
- [Getting Info of a File in Artifactory](#getting-info-of-a-file-in-artifactory)
- [Getting a listing of files and folders within a folder in Artifactory](#getting-a-listing-of-files-and-folders-within-a-folder-in-artifactory)
- [Getting Storage Summary Info of Artifactory](#getting-storage-summary-info-of-artifactory)
- [Getting package artifact Lead File](#getting-package-artifact-lead-file)
- [Triggering Storage Info Recalculation in Artifactory](#triggering-storage-info-recalculation-in-artifactory)
- [Access APIs](#access-apis)
- [Creating Access Service Manager](#creating-access-service-manager)
Expand Down Expand Up @@ -1439,6 +1440,12 @@ serviceManager.FileList("repo/path/", optionalParams)
storageInfo, err := serviceManager.GetStorageInfo()
```

#### Getting Package Artifact Lead File

```go
leadArtifact, err := serviceManager.GetPackageLeadFile()
```

#### Triggering Storage Info Recalculation in Artifactory

```go
Expand Down
5 changes: 5 additions & 0 deletions artifactory/emptymanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type ArtifactoryServicesManager interface {
GetStorageInfo() (*utils.StorageInfo, error)
CalculateStorageInfo() error
ImportReleaseBundle(string) error
GetPackageLeadFile(leadFileParams services.LeadFileParams) ([]byte, error)
}

// By using this struct, you have the option of overriding only some of the ArtifactoryServicesManager
Expand Down Expand Up @@ -470,6 +471,10 @@ func (esm *EmptyArtifactoryServicesManager) ImportReleaseBundle(string) error {
panic("Failed: Method is not implemented")
}

func (esm *EmptyArtifactoryServicesManager) GetPackageLeadFile(services.LeadFileParams) ([]byte, error) {
panic("Failed: Method is not implemented")
}

// Compile time check of interface implementation.
// Since EmptyArtifactoryServicesManager can be used by tests external to this project, we want this project's tests to fail,
// if EmptyArtifactoryServicesManager stops implementing the ArtifactoryServicesManager interface.
Expand Down
6 changes: 6 additions & 0 deletions artifactory/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ func (sm *ArtifactoryServicesManagerImp) GetRepository(repoKey string, repoDetai
return repositoriesService.Get(repoKey, repoDetails)
}

func (sm *ArtifactoryServicesManagerImp) GetPackageLeadFile(leadFileParams services.LeadFileParams) ([]byte, error) {
packageService := services.NewPackageService(sm.client)
packageService.ArtDetails = sm.config.GetServiceDetails()
return packageService.GetPackageLeadFile(leadFileParams)
}

func (sm *ArtifactoryServicesManagerImp) GetAllRepositories() (*[]services.RepositoryDetails, error) {
repositoriesService := services.NewRepositoriesService(sm.client)
repositoriesService.ArtDetails = sm.config.GetServiceDetails()
Expand Down
53 changes: 53 additions & 0 deletions artifactory/services/packages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package services

import (
"encoding/json"
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
clientUtils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"net/http"
)

const apiLeadFile = "api/packagesSearch/leadFile"

type PackageService struct {
Client *jfroghttpclient.JfrogHttpClient
ArtDetails auth.ServiceDetails
}

func NewPackageService(client *jfroghttpclient.JfrogHttpClient) *PackageService {
return &PackageService{Client: client}
}

func (ps *PackageService) GetJfrogHttpClient() *jfroghttpclient.JfrogHttpClient {
return ps.Client
}

func (ps *PackageService) GetPackageLeadFile(leadFileRequest LeadFileParams) ([]byte, error) {
requestUrl, err := clientUtils.BuildUrl(ps.ArtDetails.GetUrl(), apiLeadFile, nil)
if err != nil {
return nil, err
}

requestContent, err := json.Marshal(leadFileRequest)
if err != nil {
return nil, errorutils.CheckError(err)
}

httpClientsDetails := ps.ArtDetails.CreateHttpClientDetails()
httpClientsDetails.SetContentTypeApplicationJson()

resp, body, err := ps.Client.SendPost(requestUrl, requestContent, &httpClientsDetails)
if err != nil {
return nil, err
}
return body, errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK)
}

type LeadFileParams struct {
PackageVersion string `json:"package_version"`
PackageName string `json:"package_name"`
PackageRepoName string `json:"package_repo_name"`
PackageType string `json:"package_type"`
}
4 changes: 3 additions & 1 deletion artifactory/services/utils/tests/xray/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,9 @@ const BuildScanResultsResponse = `
]
}
`
const xscVersionResponse = `{"xsc_version": "1.0.0"}`
const xscVersionResponse = `{"xsc_version": "%s","xray_version":"3.107.8"}`

const xrayVersionResponse = `{"xray_version":"%s","xray_revision":"5735964"}`

const scanIdResponse = `{"scan_id": "3472b4e2-bddc-11ee-a9c9-acde48001122"}`

Expand Down
63 changes: 33 additions & 30 deletions artifactory/services/utils/tests/xray/server.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xray

import (
"encoding/json"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -186,17 +185,30 @@ func buildScanHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Invalid reports request", http.StatusBadRequest)
}

func xscGetVersionHandlerFunc(t *testing.T) func(w http.ResponseWriter, r *http.Request) {
func xscGetVersionHandlerFunc(t *testing.T, version string) func(w http.ResponseWriter, r *http.Request) {
expectedResponse := fmt.Sprintf(xscVersionResponse, version)
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
_, err := fmt.Fprint(w, xscVersionResponse)
_, err := fmt.Fprint(w, expectedResponse)
assert.NoError(t, err)
return
}
http.Error(w, "Invalid xsc request", http.StatusBadRequest)
}
}

func xrayGetVersionHandlerFunc(t *testing.T, version string) func(w http.ResponseWriter, r *http.Request) {
expectedResponse := fmt.Sprintf(xrayVersionResponse, version)
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
_, err := fmt.Fprint(w, expectedResponse)
assert.NoError(t, err)
return
}
http.Error(w, "Invalid xray request", http.StatusBadRequest)
}
}

func enrichGetScanId(t *testing.T) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
Expand Down Expand Up @@ -230,43 +242,34 @@ func enrichGetResults(t *testing.T) func(w http.ResponseWriter, r *http.Request)
}
}

func xscGitInfoHandlerFunc(t *testing.T) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
req, err := io.ReadAll(r.Body)
assert.NoError(t, err)
if r.Method == http.MethodPost {
var reqBody services.XscGitInfoContext
err = json.Unmarshal(req, &reqBody)
assert.NoError(t, err)
if reqBody.GitRepoUrl == "" || reqBody.BranchName == "" || reqBody.CommitHash == "" {
w.WriteHeader(http.StatusBadRequest)
_, err := fmt.Fprint(w, XscGitInfoBadResponse)
assert.NoError(t, err)
return
}
w.WriteHeader(http.StatusCreated)
_, err = fmt.Fprint(w, XscGitInfoResponse)
assert.NoError(t, err)
return
}
http.Error(w, "Invalid xsc request", http.StatusBadRequest)
}
type MockServerParams struct {
MSI string
XrayVersion string
XscVersion string
}

func StartXrayMockServer(t *testing.T) int {
params := MockServerParams{MSI: TestMultiScanId, XrayVersion: "3.0.0", XscVersion: "1.0.0"}
return StartXrayMockServerWithParams(t, params)
}

func StartXrayMockServerWithParams(t *testing.T, params MockServerParams) int {
handlers := clienttests.HttpServerHandlers{}

handlers["/"] = http.NotFound
// Xray handlers
handlers["/xray/api/v1/system/version"] = xrayGetVersionHandlerFunc(t, params.XrayVersion)
handlers["/api/xray/scanBuild"] = scanBuildHandler
handlers["/api/v2/summary/artifact"] = artifactSummaryHandler
handlers["/api/v1/entitlements/feature/"] = entitlementsHandler
handlers["/xsc/api/v1/system/version"] = xscGetVersionHandlerFunc(t)
handlers["/xsc/api/v1/gitinfo"] = xscGitInfoHandlerFunc(t)
handlers["/xray/api/v1/scan/import_xml"] = enrichGetScanId(t)
handlers[fmt.Sprintf("/xray/api/v1/scan/graph/%s", params.MSI)] = enrichGetResults(t)
handlers["/xray/api/v1/configuration/jas"] = getJasConfig(t)
getEnrichResults := fmt.Sprintf("/xray/api/v1/scan/graph/%s", TestMultiScanId)
handlers[getEnrichResults] = enrichGetResults(t)
handlers[fmt.Sprintf("/%s/", services.ReportsAPI)] = reportHandler
handlers[fmt.Sprintf("/%s/", services.BuildScanAPI)] = buildScanHandler
handlers["/"] = http.NotFound
handlers[fmt.Sprintf("/%s/", services.ReportsAPI)] = reportHandler
// Xsc handlers
handlers["/xsc/api/v1/system/version"] = xscGetVersionHandlerFunc(t, params.XscVersion)
handlers["/xray/api/v1/xsc/system/version"] = xscGetVersionHandlerFunc(t, params.XscVersion)

port, err := clienttests.StartHttpServer(handlers)
if err != nil {
Expand Down
65 changes: 65 additions & 0 deletions tests/artifactoryPackage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package tests

import (
"github.com/jfrog/jfrog-client-go/artifactory/auth"
"github.com/jfrog/jfrog-client-go/artifactory/services"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

var leadFileRequest = services.LeadFileParams{
PackageVersion: "1.0.0",
PackageName: "test-package",
PackageRepoName: "test-repo",
PackageType: "test-type",
}

func TestPackage(t *testing.T) {
initArtifactoryTest(t)
t.Run("TestGetLeadFileSuccessfully", TestGetLeadFileSuccessfully)
}

func TestGetLeadFileSuccessfully(t *testing.T) {
handlerFunc := createDefaultHandlerFunc(t)
mockServer, packageService := createMockPackageServer(t, handlerFunc)

expectedLeadFile := "path/to/lead/file"
defer mockServer.Close()

leadFilePath, err := packageService.GetPackageLeadFile(leadFileRequest)
assert.NoError(t, err)
assert.Equal(t, expectedLeadFile, string(leadFilePath))
}

func createDefaultHandlerFunc(t *testing.T) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/api/packagesSearch/leadFile" {
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
w.WriteHeader(http.StatusOK)
writeMockLeadFileResponse(t, w, []byte("path/to/lead/file"))
} else {
t.Errorf("Unexpected URL: got %s, want %s", r.RequestURI, "/api/packagesSearch/leadFile")
http.Error(w, "Not Found", http.StatusNotFound)
}
}
}

func writeMockLeadFileResponse(t *testing.T, w http.ResponseWriter, payload []byte) {
_, err := w.Write(payload)
assert.NoError(t, err)
}

func createMockPackageServer(t *testing.T, testHandler http.HandlerFunc) (*httptest.Server, *services.PackageService) {
testServer := httptest.NewServer(testHandler)

serviceDetails := auth.NewArtifactoryDetails()
serviceDetails.SetUrl(testServer.URL + "/")

packageService, err := jfroghttpclient.JfrogClientBuilder().Build()

assert.NoError(t, err)
return testServer, &services.PackageService{Client: packageService, ArtDetails: serviceDetails}
}
2 changes: 2 additions & 0 deletions tests/jfrogclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestMain(m *testing.M) {
func setupIntegrationTests() {
flag.Parse()
log.SetLogger(log.NewLogger(log.DEBUG, nil))

if *TestArtifactory || *TestDistribution || *TestXray || *TestRepositories || *TestMultipartUpload {
createArtifactoryUploadManager()
createArtifactorySearchManager()
Expand All @@ -44,6 +45,7 @@ func setupIntegrationTests() {
createArtifactoryUpdateFederatedRepositoryManager()
createArtifactoryDeleteRepositoryManager()
createArtifactoryGetRepositoryManager()
createArtifactoryGetPackageManager()
createArtifactoryReplicationCreateManager()
createArtifactoryReplicationUpdateManager()
createArtifactoryReplicationGetManager()
Expand Down
9 changes: 9 additions & 0 deletions tests/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ var (
testsUpdateFederatedRepositoryService *services.FederatedRepositoryService
testsDeleteRepositoryService *services.DeleteRepositoryService
testsRepositoriesService *services.RepositoriesService
testsPackageService *services.PackageService
testsCreateReplicationService *services.CreateReplicationService
testsUpdateReplicationService *services.UpdateReplicationService
testsReplicationGetService *services.GetReplicationService
Expand Down Expand Up @@ -365,6 +366,14 @@ func createArtifactoryGetRepositoryManager() {
testsRepositoriesService.ArtDetails = artDetails
}

func createArtifactoryGetPackageManager() {
artDetails := GetRtDetails()
client, err := createJfrogHttpClient(&artDetails)
failOnHttpClientCreation(err)
testsPackageService = services.NewPackageService(client)
testsPackageService.ArtDetails = artDetails
}

func createArtifactoryReplicationCreateManager() {
artDetails := GetRtDetails()
client, err := createJfrogHttpClient(&artDetails)
Expand Down
Loading

0 comments on commit 9026fac

Please sign in to comment.