Skip to content

feat(service-registry artifact): allow loading artifact from remote URL#1345

Merged
rkpattnaik780 merged 2 commits intomainfrom
artifact_url
Dec 17, 2021
Merged

feat(service-registry artifact): allow loading artifact from remote URL#1345
rkpattnaik780 merged 2 commits intomainfrom
artifact_url

Conversation

@rkpattnaik780
Copy link
Contributor

It should be possible to create/update artifacts using remote URLs.

Verification Steps

  1. Pass url as value for --file while creating an artifact.
rhoas service-registry artifact create --type OPENAPI --file "https://raw.githubusercontent.com/bolcom/avro-schema-viewer/master/docs/assets/avsc/1.0/schema.avsc" --artifact-id foo_id
  1. Pass url as value for --file to update an artifact.
rhoas service-registry artifact update --artifact-id foo_id --group DEFAULT --file "https://raw.githubusercontent.com/bolcom/avro-schema-viewer/master/docs/assets/avsc/1.0/schema.avsc"

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation change
  • Other (please specify)

Checklist

  • Documentation added for the feature
  • CI and all relevant tests are passing
  • Code Review completed
  • Verified independently by reviewer

@craicoverflow
Copy link
Contributor

craicoverflow commented Dec 9, 2021

I don't see any reviewer assigned for this or #1344 so not sure whether you would like them to be reviewed or not?

Copy link
Contributor

@craicoverflow craicoverflow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❯ ./rhoas service-registry artifact update --artifact-id foo_id --group DEFAULT --file "https://raw.githubusercontent.com/bolcom/avro-schema-viewer/master/docs/assets/avsc/1.0/schema.avsc"
Loading file from url: https://raw.githubusercontent.com/bolcom/avro-schema-viewer/master/docs/assets/avsc/1.0/schema.avsc
❌ 404 Not Found. Run the command in verbose mode using the -v flag to see more information

This makes it seem like the file is not found, but in actual fact it is because the artifact does not exist. The user will not know that.

Overall this works really well 👍🏻 Not approving as I think there improvements that can be made but not outright rejecting it either. If you feel you want things kept as s that is fine, just re-request my review and let me know :)

Comment on lines +48 to +97
// IsURL accepts a string and determines if it is a URL
func IsURL(s string) bool {
return strings.HasPrefix(s, "http:/") || strings.HasPrefix(s, "https:/")
}

// GetContentFromFileURL loads file content from the provided URL
func GetContentFromFileURL(url string, ctx context.Context) (*os.File, error) {

req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}

client := http.DefaultClient

resp, err := client.Do(req)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error loading file: %s", http.StatusText(resp.StatusCode))
}

respbody := resp.Body

defer resp.Body.Close()

tmpfile, err := ioutil.TempFile("", "rhoas_file-*")
if err != nil {
return nil, fmt.Errorf("error initializing temporary file: %w", err)
}

defer func() {
_ = tmpfile.Close()
_ = os.Remove(tmpfile.Name())
}()

_, err = io.Copy(tmpfile, respbody)
if err != nil {
return nil, err
}

specifiedFile, err := os.Open(tmpfile.Name())
if err != nil {
return nil, err
}

return specifiedFile, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmdutil should be strictly for utils for creating commands. These functions are technically not tied to command creation and are generally very useful anywhere, I reckon a new/separate package might be good.

}

// GetContentFromFileURL loads file content from the provided URL
func GetContentFromFileURL(url string, ctx context.Context) (*os.File, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ctx usually goes first in functions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like a good candidate for a unit test.

}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error loading file: %s", http.StatusText(resp.StatusCode))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs i18n


tmpfile, err := ioutil.TempFile("", "rhoas_file-*")
if err != nil {
return nil, fmt.Errorf("error initializing temporary file: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs i18n

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use a struct for all the utility methods to pass common things like localizer, context, it seems bit odd to have an additional argument for everything?

Copy link
Contributor

@craicoverflow craicoverflow Dec 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it also means we must continuously "break" APIs when new requirements are added such as i18n, which may not exist in a util but then if we need to add it we automatically break it..

A better thing to do might be to return a special error type like InitializeTemporaryFileErr and in the usage, interpret that and use i18n to create the message outside of the util..

Neither option seems ideal to me. Maybe merge it as it as its such a minor error, there's no point sacrificing usability/simplicity yet.

@wtrocki
Copy link
Collaborator

wtrocki commented Dec 10, 2021

It works! Great job!

@craicoverflow
Copy link
Contributor

This should be merged right?

@rkpattnaik780
Copy link
Contributor Author

This should be merged right?

Will merge once approved.

@craicoverflow
Copy link
Contributor

This should be merged right?

Will merge once approved.

I see that @wtrocki has approved. Do PRs need 2 approvals?

@@ -1,9 +1,13 @@
package util
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it pre-exists this PR, but going forward we should not call packages "util", and we should update it when we see them.

}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error loading file: %s", http.StatusText(resp.StatusCode))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i18n?


tmpfile, err := ioutil.TempFile("", "rhoas-std-input")
if err != nil {
return nil, fmt.Errorf("error initializing temporary file: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i18n?

@rkpattnaik780 rkpattnaik780 merged commit dd7f1f9 into main Dec 17, 2021
@rkpattnaik780 rkpattnaik780 deleted the artifact_url branch December 17, 2021 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants