sa: get order names from authorizations (#7435)

This removes the only place we query the requestedNames table, which
allows us to get rid of it in a subsequent PR (once this one is merged
and deployed).

Part of https://github.com/letsencrypt/boulder/issues/7432
This commit is contained in:
Jacob Hoffman-Andrews 2024-04-18 14:00:53 -07:00 committed by GitHub
parent 94d14689bf
commit 89b07f4543
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 58 deletions

View File

@ -1054,7 +1054,7 @@ var blockedKeysColumns = "keyHash, added, source, comment"
// processing, then the order is status ready.
//
// An error is returned for any other case.
func statusForOrder(ctx context.Context, s db.Selector, order *corepb.Order, now time.Time) (string, error) {
func statusForOrder(order *corepb.Order, authzValidityInfo []authzValidity, now time.Time) (string, error) {
// Without any further work we know an order with an error is invalid
if order.Error != nil {
return string(core.StatusInvalid), nil
@ -1071,13 +1071,6 @@ func statusForOrder(ctx context.Context, s db.Selector, order *corepb.Order, now
return string(core.StatusInvalid), nil
}
// Get the full Authorization objects for the order
authzValidityInfo, err := getAuthorizationStatuses(ctx, s, order.V2Authorizations)
// If there was an error getting the authorizations, return it immediately
if err != nil {
return "", err
}
// If getAuthorizationStatuses returned a different number of authorization
// objects than the order's slice of authorization IDs something has gone
// wrong worth raising an internal error about.
@ -1096,7 +1089,7 @@ func statusForOrder(ctx context.Context, s db.Selector, order *corepb.Order, now
// Loop over each of the order's authorization objects to examine the authz status
for _, info := range authzValidityInfo {
switch core.AcmeStatus(info.Status) {
switch uintToStatus[info.Status] {
case core.StatusPending:
pendingAuthzs++
case core.StatusValid:
@ -1109,7 +1102,7 @@ func statusForOrder(ctx context.Context, s db.Selector, order *corepb.Order, now
otherAuthzs++
default:
return "", berrors.InternalServerError(
"Order is in an invalid state. Authz has invalid status %s",
"Order is in an invalid state. Authz has invalid status %d",
info.Status)
}
if info.Expires.Before(now) {
@ -1162,9 +1155,12 @@ func statusForOrder(ctx context.Context, s db.Selector, order *corepb.Order, now
"authorizations", order.Id)
}
// authzValidity is a subset of authzModel
type authzValidity struct {
Status string
Expires time.Time
IdentifierType uint8 `db:"identifierType"`
IdentifierValue string `db:"identifierValue"`
Status uint8 `db:"status"`
Expires time.Time `db:"expires"`
}
// getAuthorizationStatuses takes a sequence of authz IDs, and returns the
@ -1174,14 +1170,11 @@ func getAuthorizationStatuses(ctx context.Context, s db.Selector, ids []int64) (
for _, id := range ids {
params = append(params, id)
}
var validityInfo []struct {
Status uint8
Expires time.Time
}
var validities []authzValidity
_, err := s.Select(
ctx,
&validityInfo,
fmt.Sprintf("SELECT status, expires FROM authz2 WHERE id IN (%s)",
&validities,
fmt.Sprintf("SELECT identifierType, identifierValue, status, expires FROM authz2 WHERE id IN (%s)",
db.QuestionMarks(len(ids))),
params...,
)
@ -1189,14 +1182,7 @@ func getAuthorizationStatuses(ctx context.Context, s db.Selector, ids []int64) (
return nil, err
}
allAuthzValidity := make([]authzValidity, len(validityInfo))
for i, info := range validityInfo {
allAuthzValidity[i] = authzValidity{
Status: string(uintToStatus[info.Status]),
Expires: info.Expires,
}
}
return allAuthzValidity, nil
return validities, nil
}
// authzForOrder retrieves the authorization IDs for an order.
@ -1211,23 +1197,6 @@ func authzForOrder(ctx context.Context, s db.Selector, orderID int64) ([]int64,
return v2IDs, err
}
// namesForOrder finds all of the requested names associated with an order. The
// names are returned in their reversed form (see `sa.ReverseName`).
func namesForOrder(ctx context.Context, s db.Selector, orderID int64) ([]string, error) {
var reversedNames []string
_, err := s.Select(
ctx,
&reversedNames,
`SELECT reversedName
FROM requestedNames
WHERE orderID = ?`,
orderID)
if err != nil {
return nil, err
}
return reversedNames, nil
}
// crlShardModel represents one row in the crlShards table. The ThisUpdate and
// NextUpdate fields are pointers because they are NULL-able columns.
type crlShardModel struct {

View File

@ -546,6 +546,7 @@ func (ssa *SQLStorageAuthority) NewOrderAndAuthzs(ctx context.Context, req *sapb
}
// Fourth, insert all of the requestedNames.
// TODO(#7432): Remove this
inserter, err = db.NewMultiInserter("requestedNames", []string{"orderID", "reversedName"}, "")
if err != nil {
return nil, err
@ -595,9 +596,16 @@ func (ssa *SQLStorageAuthority) NewOrderAndAuthzs(ctx context.Context, req *sapb
}
}
// Get the partial Authorization objects for the order
authzValidityInfo, err := getAuthorizationStatuses(ctx, tx, res.V2Authorizations)
// If there was an error getting the authorizations, return it immediately
if err != nil {
return nil, err
}
// Calculate the order status before returning it. Since it may have reused
// all valid authorizations the order may be "born" in a ready status.
status, err := statusForOrder(ctx, tx, res, ssa.clk.Now())
status, err := statusForOrder(res, authzValidityInfo, ssa.clk.Now())
if err != nil {
return nil, err
}

View File

@ -1272,11 +1272,6 @@ func TestNewOrderAndAuthzs(t *testing.T) {
test.AssertNotError(t, err, "Failed to count orderToAuthz entries")
test.AssertEquals(t, len(authzIDs), 4)
test.AssertDeepEquals(t, authzIDs, []int64{1, 2, 3, 4})
names, err := namesForOrder(ctx, sa.dbReadOnlyMap, order.Id)
test.AssertNotError(t, err, "namesForOrder errored")
test.AssertEquals(t, len(names), 4)
test.AssertDeepEquals(t, names, []string{"com.a", "com.b", "com.c", "com.d"})
}
// TestNewOrderAndAuthzs_NonNilInnerOrder verifies that a nil

View File

@ -673,21 +673,21 @@ func (ssa *SQLStorageAuthorityRO) GetOrder(ctx context.Context, req *sapb.OrderR
}
order.V2Authorizations = v2AuthzIDs
names, err := namesForOrder(ctx, tx, order.Id)
// Get the partial Authorization objects for the order
authzValidityInfo, err := getAuthorizationStatuses(ctx, tx, order.V2Authorizations)
// If there was an error getting the authorizations, return it immediately
if err != nil {
return nil, err
}
// The requested names are stored reversed to improve indexing performance. We
// need to reverse the reversed names here before giving them back to the
// caller.
reversedNames := make([]string, len(names))
for i, n := range names {
reversedNames[i] = ReverseName(n)
names := make([]string, 0, len(authzValidityInfo))
for _, a := range authzValidityInfo {
names = append(names, a.IdentifierValue)
}
order.Names = reversedNames
order.Names = names
// Calculate the status for the order
status, err := statusForOrder(ctx, tx, order, ssa.clk.Now())
status, err := statusForOrder(order, authzValidityInfo, ssa.clk.Now())
if err != nil {
return nil, err
}