-
Notifications
You must be signed in to change notification settings - Fork 41
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
Decouple legacy entity tables from results queries #4342
Conversation
789b288
to
6465818
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, this is not easy code to modify. About the issues with the code referencing repoName and repoOwner separately, it looks like we're either constructing the repo slug again anyway or just returning them in a generic map[string]string
through the entityInfo
variable, so it should be possible to use the name straight away hopefully?
1755b21
to
2df7309
Compare
5d15418
to
a548c03
Compare
a548c03
to
8d84ddf
Compare
8d84ddf
to
dd2dabe
Compare
entityInfo["entity_type"] = efp.Entity.Type.ToString() | ||
entityInfo["entity_id"] = rs.EntityID.String() | ||
|
||
// temporary: These will be replaced by entity_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as well as these could be simplified?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll have a set of properties we output and have a general way of displaying them, so this will be replaced with a provider-specific call IMO.
artRepoOwner := efp.Properties.GetProperty(ghprop.ArtifactPropertyRepoOwner).GetString() | ||
artRepoName := efp.Properties.GetProperty(ghprop.ArtifactPropertyRepoName).GetString() | ||
if artRepoOwner != "" && artRepoName != "" { | ||
repoPath = fmt.Sprintf("%s/%s", artRepoOwner, artRepoName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this name ever going to be used in anything but presentation? I wonder if we should make the RepoOwner and RepoName properties not tied to github provider (and move them into contants.go like we have properties.RepoPropertyIsPrivate). Then we could use this code for non-github artifacts and maybe even make the code more generic by constructing new properties and calling provider.GetEntityName(REPOSITORY, theNewProperties)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, our output is heavily tied to GitHub, this is actually used to get the alert which won't exist in other providers. I can't wait to deprecate that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Answering your question, I still think it's a github-specific attribute.
@@ -70,8 +70,6 @@ func TestListEvaluationHistoryFilters(t *testing.T) { | |||
require.Equal(t, es1, row.EvaluationID) | |||
require.Equal(t, EntitiesRepository, row.EntityType) | |||
require.Equal(t, repo1.ID, row.EntityID) | |||
require.Equal(t, repo1.RepoOwner, row.RepoOwner.String) | |||
require.Equal(t, repo1.RepoName, row.RepoName.String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did we have to remove these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because else we'd need to return the repo owner via a JOIN in the ListEvaluationHistory call. And the intent was to remove that. We should not rely on any entity-specific info.
ehs := &evaluationHistoryService{ | ||
providerManager: providerManager, | ||
propServiceBuilder: func(qtx db.ExtendQuerier) propertiessvc.PropertiesService { | ||
return propertiessvc.NewPropertiesService(qtx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be OK to just require the PropertiesService interface as a parameter but the options don't hurt..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was done for testing only.
internal/history/service.go
Outdated
return nil, fmt.Errorf("error fetching entity for properties: %w", err) | ||
} | ||
|
||
err = propsvc.RetrieveAllPropertiesForEntity(ctx, efp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is potentially a lot of calls isn't it? Do we actually need up-to-date data here, couldn't we just fetch the entities and properties from cache regardless of whether it's expired or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are at a weird point where we don't have everything in cache just yet. The idea is to fetch from cache if it's possible, and persist it if it isn't there. Perhaps I should instead add "options" to this call and rely on the cache even if the data is marked as stale. wdyt?
} | ||
|
||
fetchByProps, err := properties.NewProperties(map[string]any{ | ||
properties.PropertyName: ent.Name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not saying this is right or wrong and it's not for this PR, but I was wondering whether the way I coded up fetching properties is correct - for example for PRs you need the PR number, the repo owner and repo name. So the way the fetcher retrieves the information is either 1) those properties are in the lookByProps properties structure or 2) the fetcher parses the name.
I wonder if doing 2) is too "magic" and if a function like this one should rather just return all the cached properties and let the fetcher decide based on the properties and the type of the entity.
// RetrieveAllPropertiesForEntity fetches a single property for the given an entity | ||
// for properties model. Note that properties will be updated in place. | ||
func (ps *propertiesService) RetrieveAllPropertiesForEntity( | ||
ctx context.Context, efp *models.EntityForProperties, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, but do you think that in a follow up we could change RetrieveAllProperties to accept EntityForProperties or just an Entity that alrady has projectID, providerID and type and do something like:
newProps, err := ps.RetrieveAllProperties(ctx, prov, entity, lookupProps)
efp := NewEntityFromPropertiesWithInstance(entity, newProps)
internal/entities/models/models.go
Outdated
*EntityWithProperties | ||
|
||
// Provider is the provider for the entity | ||
Provider provifv1.Provider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why keep track of the provider and not just use the providerID in the EntityWithProperties? I wonder if the cleanest way would be to just pass the providerID to the propertyService, let the propertyService structure contain a providerManager and always instantiate the provider...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good observation. I was just trying to make it easier to instantiate everything. But this could actually be moved to the RetrieveAllPropertiesForEntity
so we would not need the new wrapper. Let me refactor this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work!
The code reads easier now that it doesn't handle the entity type separately. I put some comments inline, they are mostly to make sure that the original design of the PropertyService wasn't bad to start with and that we're not adding hacks to address the shortcomings instead.
The biggest question I have is though - why do we call the Refreshes in this service at all and not just rely on the database properties? Wouldn't we cause a lot of upstream traffic this way?
This is another step into moving away from the central entity tables and into the new per-entity tables. Signed-off-by: Juan Antonio Osorio <[email protected]>
dd2dabe
to
fa3faac
Compare
I added a comment about that above. I think we can deal with that by adding options to the retrieve calls. |
This is not needed and redundant. Instead the logic is moved towards the properties service Signed-off-by: Juan Antonio Osorio <[email protected]>
Signed-off-by: Juan Antonio Osorio <[email protected]>
if rs.EntityType == db.EntitiesRepository { | ||
entityInfo["repository_id"] = efp.Entity.ID.String() | ||
} else if rs.EntityType == db.EntitiesArtifact { | ||
entityInfo["artifact_id"] = efp.Entity.ID.String() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could just use the upstream ID as a string here to simplify the logic (OK in a follow-up)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we use these for anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I don't know. Let's try removing them subsequently.
Summary
This is another step into moving away from the central entity tables and
into the new per-entity tables.
Fixes #4316
Change Type
Mark the type of change your PR introduces:
Testing
Review Checklist: