Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Lifecycle Release Bundle Distribute #797

Merged
merged 4 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1614,9 +1614,9 @@ summary, err := distManager.SignReleaseBundle(params)
#### Async Distributing a Release Bundle v1

```go
params := services.NewDistributeReleaseBundleParams("bundle-name", "1")
distributionRules := utils.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*utils.DistributionCommonParams{distributionRules}
params := distribution.NewDistributeReleaseBundleParams("bundle-name", "1")
distributionRules := distribution.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*distribution.DistributionCommonParams{distributionRules}
// Auto-creating repository if it does not exist
autoCreateRepo := true
err := distManager.DistributeReleaseBundle(params, autoCreateRepo)
Expand All @@ -1625,9 +1625,9 @@ err := distManager.DistributeReleaseBundle(params, autoCreateRepo)
#### Sync Distributing a Release Bundle v1

```go
params := services.NewDistributeReleaseBundleParams("bundle-name", "1")
distributionRules := utils.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*utils.DistributionCommonParams{distributionRules}
params := distribution.NewDistributeReleaseBundleParams("bundle-name", "1")
distributionRules := distribution.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*distribution.DistributionCommonParams{distributionRules}
// Auto-creating repository if it does not exist
autoCreateRepo := true
// Wait up to 120 minutes for the release bundle v1 distribution
Expand All @@ -1654,8 +1654,8 @@ status, err := distributeBundleService.GetStatus(params)
```go
params := services.NewDeleteReleaseBundleParams("bundle-name", "1")
params.DeleteFromDistribution = true
distributionRules := utils.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*utils.DistributionCommonParams{distributionRules}
distributionRules := distribution.DistributionCommonParams{SiteName: "Swamp-1", "CityName": "Tel-Aviv", "CountryCodes": []string{"123"}}}
params.DistributionRules = []*distribution.DistributionCommonParams{distributionRules}
// Set to true to enable sync deletion (the command execution will end when the deletion process ends).
param.Sync = true
// Max minutes to wait for sync deletion.
Expand Down
15 changes: 9 additions & 6 deletions distribution/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/jfrog/jfrog-client-go/distribution/services"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/distribution"
)

type DistributionServicesManager struct {
Expand Down Expand Up @@ -57,22 +58,24 @@ func (sm *DistributionServicesManager) SignReleaseBundle(params services.SignBun
return signBundleService.SignReleaseBundle(params)
}

func (sm *DistributionServicesManager) DistributeReleaseBundle(params services.DistributionParams, autoCreateRepo bool) error {
distributeBundleService := services.NewDistributeReleaseBundleService(sm.client)
func (sm *DistributionServicesManager) DistributeReleaseBundle(params distribution.DistributionParams, autoCreateRepo bool) error {
distributeBundleService := services.NewDistributeReleaseBundleV1Service(sm.client)
distributeBundleService.DistDetails = sm.config.GetServiceDetails()
distributeBundleService.DryRun = sm.config.IsDryRun()
distributeBundleService.AutoCreateRepo = autoCreateRepo
return distributeBundleService.Distribute(params)
distributeBundleService.DistributeParams = params
return distributeBundleService.Distribute()
}

func (sm *DistributionServicesManager) DistributeReleaseBundleSync(params services.DistributionParams, maxWaitMinutes int, autoCreateRepo bool) error {
distributeBundleService := services.NewDistributeReleaseBundleService(sm.client)
func (sm *DistributionServicesManager) DistributeReleaseBundleSync(params distribution.DistributionParams, maxWaitMinutes int, autoCreateRepo bool) error {
distributeBundleService := services.NewDistributeReleaseBundleV1Service(sm.client)
RobiNino marked this conversation as resolved.
Show resolved Hide resolved
distributeBundleService.DistDetails = sm.config.GetServiceDetails()
distributeBundleService.DryRun = sm.config.IsDryRun()
distributeBundleService.MaxWaitMinutes = maxWaitMinutes
distributeBundleService.Sync = true
distributeBundleService.AutoCreateRepo = autoCreateRepo
return distributeBundleService.Distribute(params)
distributeBundleService.DistributeParams = params
return distributeBundleService.Distribute()
}

func (sm *DistributionServicesManager) GetDistributionStatus(params services.DistributionStatusParams) (*[]services.DistributionStatusResponse, error) {
Expand Down
13 changes: 7 additions & 6 deletions distribution/services/deleteremote.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/distribution"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"net/http"
Expand Down Expand Up @@ -43,9 +44,9 @@ func (dr *DeleteReleaseBundleService) IsDryRun() bool {
}

func (dr *DeleteReleaseBundleService) DeleteDistribution(deleteDistributionParams DeleteDistributionParams) error {
var distributionRules []DistributionRulesBody
var distributionRules []distribution.DistributionRulesBody
for _, rule := range deleteDistributionParams.DistributionRules {
distributionRule := DistributionRulesBody{
distributionRule := distribution.DistributionRulesBody{
SiteName: rule.GetSiteName(),
CityName: rule.GetCityName(),
CountryCodes: rule.GetCountryCodes(),
Expand All @@ -61,7 +62,7 @@ func (dr *DeleteReleaseBundleService) DeleteDistribution(deleteDistributionParam
}

deleteDistribution := DeleteRemoteDistributionBody{
DistributionBody: DistributionBody{
ReleaseBundleDistributeV1Body: distribution.ReleaseBundleDistributeV1Body{
DryRun: dr.DryRun,
DistributionRules: distributionRules,
},
Expand Down Expand Up @@ -133,12 +134,12 @@ func (dr *DeleteReleaseBundleService) waitForDeletion(name, version string) erro
}

type DeleteRemoteDistributionBody struct {
DistributionBody
distribution.ReleaseBundleDistributeV1Body
OnSuccess OnSuccess `json:"on_success"`
}

type DeleteDistributionParams struct {
DistributionParams
distribution.DistributionParams
DeleteFromDistribution bool
Sync bool
// Max time in minutes to wait for sync distribution to finish.
Expand All @@ -147,7 +148,7 @@ type DeleteDistributionParams struct {

func NewDeleteReleaseBundleParams(name, version string) DeleteDistributionParams {
return DeleteDistributionParams{
DistributionParams: DistributionParams{
DistributionParams: distribution.DistributionParams{
Name: name,
Version: version,
},
Expand Down
138 changes: 44 additions & 94 deletions distribution/services/distribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,109 +3,88 @@ package services
import (
"encoding/json"
"fmt"
"net/http"

artifactoryUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
"github.com/jfrog/jfrog-client-go/auth"
distributionUtils "github.com/jfrog/jfrog-client-go/distribution/services/utils"
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
"github.com/jfrog/jfrog-client-go/utils"
clientUtils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/distribution"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
)

const defaultMaxWaitMinutes = 60 // 1 hour
const DefaultDistributeSyncSleepIntervalSeconds = 10 // 10 seconds

type DistributeReleaseBundleService struct {
type DistributeReleaseBundleV1Service struct {
client *jfroghttpclient.JfrogHttpClient
DistDetails auth.ServiceDetails
DryRun bool
Sync bool
AutoCreateRepo bool
// Max time in minutes to wait for sync distribution to finish.
MaxWaitMinutes int
MaxWaitMinutes int
DistributeParams distribution.DistributionParams
}

func NewDistributeReleaseBundleService(client *jfroghttpclient.JfrogHttpClient) *DistributeReleaseBundleService {
return &DistributeReleaseBundleService{client: client}
func (dr *DistributeReleaseBundleV1Service) GetHttpClient() *jfroghttpclient.JfrogHttpClient {
return dr.client
}

func (dr *DistributeReleaseBundleService) GetDistDetails() auth.ServiceDetails {
func (dr *DistributeReleaseBundleV1Service) ServiceDetails() auth.ServiceDetails {
return dr.DistDetails
}

func (dr *DistributeReleaseBundleService) Distribute(distributeParams DistributionParams) error {
var distributionRules []DistributionRulesBody
for _, spec := range distributeParams.DistributionRules {
distributionRule := DistributionRulesBody{
SiteName: spec.GetSiteName(),
CityName: spec.GetCityName(),
CountryCodes: spec.GetCountryCodes(),
}
distributionRules = append(distributionRules, distributionRule)
}
distribution := &DistributionBody{
DryRun: dr.DryRun,
DistributionRules: distributionRules,
AutoCreateRepo: dr.AutoCreateRepo,
}
func (dr *DistributeReleaseBundleV1Service) IsDryRun() bool {
return dr.DryRun
}

trackerId, err := dr.execDistribute(distributeParams.Name, distributeParams.Version, distribution)
if err != nil || !dr.Sync || dr.DryRun {
return err
}
func (dr *DistributeReleaseBundleV1Service) IsSync() bool {
return dr.Sync
}

// Sync distribution
return dr.waitForDistribution(&distributeParams, trackerId)
func (dr *DistributeReleaseBundleV1Service) GetMaxWaitMinutes() int {
return dr.MaxWaitMinutes
}

func (dr *DistributeReleaseBundleService) execDistribute(name, version string, distribution *DistributionBody) (json.Number, error) {
httpClientsDetails := dr.DistDetails.CreateHttpClientDetails()
content, err := json.Marshal(distribution)
if err != nil {
return "", errorutils.CheckError(err)
}
dryRunStr := ""
if distribution.DryRun {
dryRunStr = "[Dry run] "
}
log.Info(dryRunStr + "Distributing: " + name + "/" + version)
func (dr *DistributeReleaseBundleV1Service) GetRestApi(name, version string) string {
return "api/v1/distribution/" + name + "/" + version
}

url := dr.DistDetails.GetUrl() + "api/v1/distribution/" + name + "/" + version
artifactoryUtils.SetContentType("application/json", &httpClientsDetails.Headers)
resp, body, err := dr.client.SendPost(url, content, &httpClientsDetails)
if err != nil {
return "", err
}
if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK, http.StatusAccepted); err != nil {
return "", err
}
response := DistributionResponseBody{}
err = json.Unmarshal(body, &response)
if err != nil {
return "", errorutils.CheckError(err)
func (dr *DistributeReleaseBundleV1Service) GetDistributeBody() any {
return distribution.CreateDistributeV1Body(dr.DistributeParams, dr.DryRun, dr.AutoCreateRepo)
}

func (dr *DistributeReleaseBundleV1Service) GetDistributionParams() distribution.DistributionParams {
return dr.DistributeParams
}

func NewDistributeReleaseBundleV1Service(client *jfroghttpclient.JfrogHttpClient) *DistributeReleaseBundleV1Service {
return &DistributeReleaseBundleV1Service{client: client}
}

func (dr *DistributeReleaseBundleV1Service) Distribute() error {
trackerId, err := distribution.DoDistribute(dr)
if err != nil || !dr.IsSync() || dr.IsDryRun() {
return err
}

log.Debug("Distribution response:", resp.Status)
log.Debug(utils.IndentJson(body))
return response.TrackerId, nil
// Sync distribution
return dr.waitForDistribution(&dr.DistributeParams, trackerId)
}

func (dr *DistributeReleaseBundleService) waitForDistribution(distributeParams *DistributionParams, trackerId json.Number) error {
distributeBundleService := NewDistributionStatusService(dr.client)
distributeBundleService.DistDetails = dr.GetDistDetails()
func (dr *DistributeReleaseBundleV1Service) waitForDistribution(distributeParams *distribution.DistributionParams, trackerId json.Number) error {
distributeBundleService := NewDistributionStatusService(dr.GetHttpClient())
distributeBundleService.DistDetails = dr.ServiceDetails()
distributionStatusParams := DistributionStatusParams{
Name: distributeParams.Name,
Version: distributeParams.Version,
TrackerId: trackerId.String(),
}
maxWaitMinutes := defaultMaxWaitMinutes
if dr.MaxWaitMinutes >= 1 {
maxWaitMinutes = dr.MaxWaitMinutes
if dr.GetMaxWaitMinutes() >= 1 {
maxWaitMinutes = dr.GetMaxWaitMinutes()
}
distributingMessage := fmt.Sprintf("Sync: Distributing %s/%s...", distributeParams.Name, distributeParams.Version)
retryExecutor := &utils.RetryExecutor{
retryExecutor := &clientUtils.RetryExecutor{
MaxRetries: maxWaitMinutes * 60 / DefaultDistributeSyncSleepIntervalSeconds,
RetriesIntervalMilliSecs: DefaultDistributeSyncSleepIntervalSeconds * 1000,
ErrorMessage: "",
Expand All @@ -120,7 +99,7 @@ func (dr *DistributeReleaseBundleService) waitForDistribution(distributeParams *
if err != nil {
return false, errorutils.CheckError(err)
}
return false, errorutils.CheckErrorf("Distribution failed: " + utils.IndentJson(bytes))
return false, errorutils.CheckErrorf("Distribution failed: " + clientUtils.IndentJson(bytes))
}
if (*response)[0].Status == Completed {
log.Info("Distribution Completed!")
Expand All @@ -133,32 +112,3 @@ func (dr *DistributeReleaseBundleService) waitForDistribution(distributeParams *
}
return retryExecutor.Execute()
}

type DistributionBody struct {
DryRun bool `json:"dry_run"`
DistributionRules []DistributionRulesBody `json:"distribution_rules"`
AutoCreateRepo bool `json:"auto_create_missing_repositories,omitempty"`
}

type DistributionRulesBody struct {
SiteName string `json:"site_name,omitempty"`
CityName string `json:"city_name,omitempty"`
CountryCodes []string `json:"country_codes,omitempty"`
}

type DistributionResponseBody struct {
TrackerId json.Number `json:"id"`
}

type DistributionParams struct {
DistributionRules []*distributionUtils.DistributionCommonParams
Name string
Version string
}

func NewDistributeReleaseBundleParams(name, version string) DistributionParams {
return DistributionParams{
Name: name,
Version: version,
}
}
17 changes: 9 additions & 8 deletions distribution/services/getstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package services
import (
"encoding/json"
"errors"
"github.com/jfrog/jfrog-client-go/utils/distribution"
"net/http"
"strings"

Expand Down Expand Up @@ -109,14 +110,14 @@ const (
)

type DistributionStatusResponse struct {
Id json.Number `json:"distribution_id"`
FriendlyId json.Number `json:"distribution_friendly_id,omitempty"`
Type DistributionType `json:"type,omitempty"`
Name string `json:"release_bundle_name,omitempty"`
Version string `json:"release_bundle_version,omitempty"`
Status DistributionStatus `json:"status,omitempty"`
DistributionRules []DistributionRulesBody `json:"distribution_rules,omitempty"`
Sites []DistributionSiteStatus `json:"sites,omitempty"`
Id json.Number `json:"distribution_id"`
FriendlyId json.Number `json:"distribution_friendly_id,omitempty"`
Type DistributionType `json:"type,omitempty"`
Name string `json:"release_bundle_name,omitempty"`
Version string `json:"release_bundle_version,omitempty"`
Status DistributionStatus `json:"status,omitempty"`
DistributionRules []distribution.DistributionRulesBody `json:"distribution_rules,omitempty"`
Sites []DistributionSiteStatus `json:"sites,omitempty"`
}

type DistributionSiteStatus struct {
Expand Down
Loading
Loading