ocket8888 commented on a change in pull request #5071:
URL: https://github.com/apache/trafficcontrol/pull/5071#discussion_r504230624
##########
File path: lib/go-tc/deliveryservice_requests.go
##########
@@ -547,3 +625,372 @@ func (r RequestStatus) ValidTransition(to RequestStatus)
error {
}
return errors.New("invalid transition from " + string(r) + " to " +
string(to))
}
+
+// DSRChangeType is an "enumerated" string type that encodes the legal values
of
+// a Delivery Service Request's Change Type.
+type DSRChangeType string
+
+// These are the valid values for Delivery Service Request Change Types.
+const (
+ // The original Delivery Service is being modified to match the
requested
+ // one.
+ DSRChangeTypeUpdate = DSRChangeType("update")
+ // The requested Delivery Service is being created.
+ DSRChangeTypeCreate = DSRChangeType("create")
+ // The requested Delivery Service is being deleted.
+ DSRChangeTypeDelete = DSRChangeType("delete")
+)
+
+// DSRChangeTypeFromString converts the passed string to a DSRChangeType
+// (case-insensitive), returning an error if the string is not a valid
+// Delivery Service Request Change Type.
+func DSRChangeTypeFromString(s string) (DSRChangeType, error) {
+ switch strings.ToLower(s) {
+ case "update":
+ return DSRChangeTypeUpdate, nil
+ case "create":
+ return DSRChangeTypeCreate, nil
+ case "delete":
+ return DSRChangeTypeDelete, nil
+ }
+ return "INVALID", fmt.Errorf("invalid Delivery Service Request
changeType: '%s'", s)
+}
+
+// String implements the fmt.Stringer interface, returning a textual
+// representation of the DSRChangeType.
+func (dsrct DSRChangeType) String() string {
+ return string(dsrct)
+}
+
+// MarshalJSON implements the encoding/json.Marshaller interface.
+func (dsrct DSRChangeType) MarshalJSON() ([]byte, error) {
+ return json.Marshal(string(dsrct))
+}
+
+// UnmarshalJSON implements the encoding/json.Unmarshaller interface.
+func (dsrct *DSRChangeType) UnmarshalJSON(b []byte) error {
+ // This should only happen if this method is called directly;
encoding/json
+ // itself guards against this.
+ if dsrct == nil {
+ return errors.New("UnmarshalJSON(nil *tc.DSRChangeType)")
+ }
+
+ ctStr, err := strconv.Unquote(string(b))
+ if err != nil {
+ return err
+ }
+
+ ct, err := DSRChangeTypeFromString(ctStr)
+ if err != nil {
+ return err
+ }
+ *dsrct = ct
+ return nil
+}
+
+// DeliveryServiceRequestV30 is the type of a Delivery Service Request in
+// Traffic Ops API version 3.0.
+type DeliveryServiceRequestV30 struct {
+ // Assignee is the username of the user assigned to the Delivery Service
+ // Request, if any.
+ Assignee *string `json:"assignee"`
+ // AssigneeID is the integral, unique identifier of the user assigned
to the
+ // Delivery Service Request, if any.
+ AssigneeID *int `json:"-" db:"assignee_id"`
+ // Author is the username of the user who created the Delivery Service
+ // Request.
+ Author string `json:"author"`
+ // AuthorID is the integral, unique identifier of the user who created
the
+ // Delivery Service Request, if/when it is known.
+ AuthorID *int `json:"-" db:"author_id"`
+ // ChangeType represents the type of change being made, must be one of
+ // "create", "change" or "delete".
+ ChangeType DSRChangeType `json:"changeType" db:"change_type"`
+ // CreatedAt is the date/time at which the Delivery Service Request was
+ // created.
+ CreatedAt time.Time `json:"createdAt" db:"created_at"`
+ // ID is the integral, unique identifier for the Delivery Service
Request
+ // if/when it is known.
+ ID *int `json:"id" db:"id"`
+ // LastEditedBy is the username of the user by whom the Delivery Service
+ // Request was last edited.
+ LastEditedBy string `json:"lastEditedBy"`
+ // LastEditedByID is the integral, unique identifier of the user by
whom the
+ // Delivery Service Request was last edited, if/when it is known.
+ LastEditedByID *int `json:"-" db:"last_edited_by_id"`
+ // LastUpdated is the date/time at which the Delivery Service was last
+ // modified.
+ LastUpdated time.Time `json:"lastUpdated" db:"last_updated"`
+ // Original is the original Delivery Service for which changes are
+ // requested. This is present in responses only for ChangeTypes
'change' and
+ // 'delete', and is only required in requests where ChangeType is
'delete'.
+ Original *DeliveryServiceV30 `json:"original,omitempty" db:"original"`
+ // Requested is the set of requested changes. This is present in
responses
+ // only for ChangeTypes 'change' and 'create', and is only required in
+ // requests in those cases.
+ Requested *DeliveryServiceV30 `json:"requested,omitempty"
db:"deliveryservice"`
+ // Status is the status of the Delivery Service Request.
+ Status RequestStatus `json:"status" db:"status"`
+ // Used internally to define the affected Delivery Service.
+ XMLID string `json:"-"`
+}
+
+// SetXMLID sets the XMLID correctly from the "Original" or "Requested"
+// Delivery Service's XMLID according to the DSR's change type. Leaves it
+// unset if the appropriate DS property is nil, or if said DS's XMLID is nil.
+func (dsr *DeliveryServiceRequestV30) SetXMLID() {
+ if dsr == nil {
+ return
+ }
+
+ if dsr.ChangeType == DSRChangeTypeDelete && dsr.Original != nil &&
dsr.Original.XMLID != nil {
+ dsr.XMLID = *dsr.Original.XMLID
+ return
+ }
+
+ if dsr.Requested != nil && dsr.Requested.XMLID != nil {
+ dsr.XMLID = *dsr.Requested.XMLID
+ }
+}
+
+// IsOpen returns whether or not the Delivery Service Request is still "open" -
+// i.e. has not been rejected or completed.
+func (dsr DeliveryServiceRequestV30) IsOpen() bool {
+ return !dsr.IsClosed()
+}
+
+// IsClosed returns whether or not the Delivery Service Request has been
+// "closed", by being either rejected or completed.
+func (dsr DeliveryServiceRequestV30) IsClosed() bool {
+ return dsr.Status == RequestStatusComplete || dsr.Status ==
RequestStatusRejected || dsr.Status == RequestStatusPending
+}
+
+// Downgrade coerces the DeliveryServiceRequestV30 to the older
+// DeliveryServiceRequestV15 structure.
+//
+// "XMLID" will be determined from the Original, if it exists, otherwise from
+// Requested.
+//
+// All reference properties are "deep"-copied so they may be modified without
+// affecting the original. However, DeliveryService is constructed as a "deep"
+// copy of "Requested", but the properties of the underlying
+// DeliveryServiceNullableV15 are "shallow" copied, and so modifying them *can*
+// affect the original and vice-versa.
+func (dsr DeliveryServiceRequestV30) Downgrade() DeliveryServiceRequestV15 {
+ downgraded := DeliveryServiceRequestV15{
+ Author: new(string),
+ ChangeType: new(string),
+ DeliveryService: new(DeliveryServiceV30),
+ LastEditedBy: new(string),
+ Status: new(RequestStatus),
+ }
+ if dsr.Assignee != nil {
+ downgraded.Assignee = new(string)
+ *downgraded.Assignee = *dsr.Assignee
+ }
+ if dsr.AssigneeID != nil {
+ downgraded.AssigneeID = new(int)
+ *downgraded.AssigneeID = *dsr.AssigneeID
+ }
+ *downgraded.Author = dsr.Author
+ if dsr.AuthorID != nil {
+ downgraded.AuthorID = new(IDNoMod)
+ *downgraded.AuthorID = IDNoMod(*dsr.AuthorID)
+ }
+ *downgraded.ChangeType = dsr.ChangeType.String()
+ downgraded.CreatedAt = TimeNoModFromTime(dsr.CreatedAt)
+ *downgraded.DeliveryService = *dsr.Requested
+ if dsr.ID != nil {
+ downgraded.ID = new(int)
+ *downgraded.ID = *dsr.ID
+ }
+ *downgraded.LastEditedBy = dsr.LastEditedBy
+ if dsr.LastEditedByID != nil {
+ downgraded.LastEditedByID = new(IDNoMod)
+ *downgraded.LastEditedByID = IDNoMod(*dsr.LastEditedByID)
+ }
+ downgraded.LastUpdated = TimeNoModFromTime(dsr.LastUpdated)
+ *downgraded.Status = dsr.Status
+ if dsr.Original != nil && dsr.Original.XMLID != nil {
+ downgraded.XMLID = new(string)
+ *downgraded.XMLID = *dsr.Original.XMLID
+ } else if dsr.Requested.XMLID != nil {
+ downgraded.XMLID = new(string)
+ *downgraded.XMLID = *dsr.Requested.XMLID
+ }
+ return downgraded
+}
+
+// String encodes the DeliveryServiceRequestV30 as a string, in the format
+// "DeliveryServiceRequestV30({{Property}}={{Value}}[,
{{Property}}={{Value}}]+)".
+//
+// If a property is a pointer value, then its dereferenced value is used -
+// unless it's nil, in which case "<nil>" is used as the value. Original and
+// Requested are omitted, because of how large they are. Times are formatted in
+// RFC3339 format.
+func (dsr DeliveryServiceRequestV30) String() string {
+ var builder strings.Builder
+ builder.Write([]byte("DeliveryServiceRequestV30(Assignee="))
+ if dsr.Assignee != nil {
+ builder.WriteRune('"')
+ builder.WriteString(*dsr.Assignee)
+ builder.WriteRune('"')
+ } else {
+ builder.Write([]byte("<nil>"))
+ }
+ builder.Write([]byte(", AssigneeID="))
+ if dsr.AssigneeID != nil {
+ builder.WriteString(strconv.Itoa(*dsr.AssigneeID))
+ } else {
+ builder.Write([]byte("<nil>"))
+ }
+ builder.Write([]byte(`, Author="`))
+ builder.WriteString(dsr.Author)
+ builder.Write([]byte(`", AuthorID=`))
+ if dsr.AuthorID != nil {
+ builder.WriteString(strconv.Itoa(*dsr.AuthorID))
+ } else {
+ builder.Write([]byte("<nil>"))
+ }
+ builder.Write([]byte(`, ChangeType="`))
+ builder.WriteString(dsr.ChangeType.String())
+ builder.Write([]byte(`", CreatedAt=`))
+ builder.WriteString(dsr.CreatedAt.Format(time.RFC3339))
+ builder.Write([]byte(", ID="))
+ if dsr.ID != nil {
+ builder.WriteString(strconv.Itoa(*dsr.ID))
+ } else {
+ builder.Write([]byte("<nil>"))
+ }
+ builder.Write([]byte(`, LastEditedBy="`))
+ builder.WriteString(dsr.LastEditedBy)
+ builder.Write([]byte(`", LastEditedByID=`))
+ if dsr.LastEditedByID != nil {
+ builder.WriteString(strconv.Itoa(*dsr.LastEditedByID))
+ } else {
+ builder.Write([]byte("<nil>"))
+ }
+ builder.Write([]byte(`, LastUpdated=`))
+ builder.WriteString(dsr.LastUpdated.Format(time.RFC3339))
+ builder.Write([]byte(`, Status="`))
+ builder.WriteString(dsr.Status.String())
+ builder.Write([]byte(`")`))
+ return builder.String()
+}
+
+// Validate satisfies the
+//
github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api.ParseValidator
+// interface.
+func (dsr *DeliveryServiceRequestV30) Validate(tx *sql.Tx) error {
+ if tx == nil {
+ return errors.New("unknown error")
+ }
+
+ fromStatus := RequestStatusDraft
+ if dsr.ID != nil && *dsr.ID > 0 {
+ if err := tx.QueryRow(`SELECT status FROM
deliveryservice_request WHERE id=$1`, *dsr.ID).Scan(&fromStatus); err != nil {
+ return err
+ }
Review comment:
nvm, I've got that backwards. I think I'll just not use the
`ParseValidator` interface.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]