github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/webhook/converter.go (about) 1 package webhook 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/auth" 10 11 "github.com/kyma-incubator/compass/components/director/internal/repo" 12 13 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 14 15 "github.com/kyma-incubator/compass/components/director/internal/model" 16 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 17 "github.com/pkg/errors" 18 ) 19 20 // AuthConverter missing godoc 21 // 22 //go:generate mockery --name=AuthConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 23 type AuthConverter interface { 24 ToGraphQL(in *model.Auth) (*graphql.Auth, error) 25 InputFromGraphQL(in *graphql.AuthInput) (*model.AuthInput, error) 26 } 27 28 type converter struct { 29 authConverter AuthConverter 30 } 31 32 // NewConverter missing godoc 33 func NewConverter(authConverter AuthConverter) *converter { 34 return &converter{authConverter: authConverter} 35 } 36 37 // ToGraphQL missing godoc 38 func (c *converter) ToGraphQL(in *model.Webhook) (*graphql.Webhook, error) { 39 if in == nil { 40 return nil, nil 41 } 42 43 auth, err := c.authConverter.ToGraphQL(in.Auth) 44 if err != nil { 45 return nil, errors.Wrap(err, "while converting Auth input") 46 } 47 48 var webhookMode *graphql.WebhookMode 49 if in.Mode != nil { 50 mode := graphql.WebhookMode(*in.Mode) 51 webhookMode = &mode 52 } 53 54 var appID *string 55 var runtimeID *string 56 var appTemplateID *string 57 var intSystemID *string 58 var formationTemplateID *string 59 switch in.ObjectType { 60 case model.ApplicationWebhookReference: 61 appID = &in.ObjectID 62 case model.RuntimeWebhookReference: 63 runtimeID = &in.ObjectID 64 case model.ApplicationTemplateWebhookReference: 65 appTemplateID = &in.ObjectID 66 case model.IntegrationSystemWebhookReference: 67 intSystemID = &in.ObjectID 68 case model.FormationTemplateWebhookReference: 69 formationTemplateID = &in.ObjectID 70 } 71 72 return &graphql.Webhook{ 73 ID: in.ID, 74 ApplicationID: appID, 75 ApplicationTemplateID: appTemplateID, 76 RuntimeID: runtimeID, 77 IntegrationSystemID: intSystemID, 78 FormationTemplateID: formationTemplateID, 79 Type: graphql.WebhookType(in.Type), 80 Mode: webhookMode, 81 URL: in.URL, 82 Auth: auth, 83 CorrelationIDKey: in.CorrelationIDKey, 84 RetryInterval: in.RetryInterval, 85 Timeout: in.Timeout, 86 URLTemplate: in.URLTemplate, 87 InputTemplate: in.InputTemplate, 88 HeaderTemplate: in.HeaderTemplate, 89 OutputTemplate: in.OutputTemplate, 90 StatusTemplate: in.StatusTemplate, 91 CreatedAt: timePtrToTimestampPtr(in.CreatedAt), 92 }, nil 93 } 94 95 // ToModel converts graphql.Webhook to model.Webhook 96 func (c *converter) ToModel(in *graphql.Webhook) (*model.Webhook, error) { 97 if in == nil { 98 return nil, nil 99 } 100 101 authModel, err := auth.ToModel(in.Auth) 102 if err != nil { 103 return nil, err 104 } 105 106 var objectID string 107 var objectType model.WebhookReferenceObjectType 108 if in.ApplicationID != nil { 109 objectID = *in.ApplicationID 110 objectType = model.ApplicationWebhookReference 111 } else if in.RuntimeID != nil { 112 objectID = *in.RuntimeID 113 objectType = model.RuntimeWebhookReference 114 } else if in.ApplicationTemplateID != nil { 115 objectID = *in.ApplicationTemplateID 116 objectType = model.ApplicationTemplateWebhookReference 117 } else if in.IntegrationSystemID != nil { 118 objectID = *in.IntegrationSystemID 119 objectType = model.IntegrationSystemWebhookReference 120 } else if in.FormationTemplateID != nil { 121 objectID = *in.FormationTemplateID 122 objectType = model.FormationTemplateWebhookReference 123 } else { 124 objectType = model.UnknownWebhookReference 125 } 126 127 var webhookMode *model.WebhookMode 128 if in.Mode != nil { 129 mode := model.WebhookMode(*in.Mode) 130 webhookMode = &mode 131 } 132 133 var createdAt *time.Time = nil 134 if in.CreatedAt != nil { 135 t := time.Time(*(in.CreatedAt)) 136 createdAt = &t 137 } 138 139 return &model.Webhook{ 140 ID: in.ID, 141 ObjectID: objectID, 142 ObjectType: objectType, 143 CorrelationIDKey: in.CorrelationIDKey, 144 Type: model.WebhookType(in.Type), 145 URL: in.URL, 146 Auth: authModel, 147 Mode: webhookMode, 148 RetryInterval: in.RetryInterval, 149 Timeout: in.Timeout, 150 URLTemplate: in.URLTemplate, 151 InputTemplate: in.InputTemplate, 152 HeaderTemplate: in.HeaderTemplate, 153 OutputTemplate: in.OutputTemplate, 154 StatusTemplate: in.StatusTemplate, 155 CreatedAt: createdAt, 156 }, nil 157 } 158 159 // MultipleToGraphQL missing godoc 160 func (c *converter) MultipleToGraphQL(in []*model.Webhook) ([]*graphql.Webhook, error) { 161 webhooks := make([]*graphql.Webhook, 0, len(in)) 162 for _, r := range in { 163 if r == nil { 164 continue 165 } 166 167 webhook, err := c.ToGraphQL(r) 168 if err != nil { 169 return nil, err 170 } 171 172 webhooks = append(webhooks, webhook) 173 } 174 175 return webhooks, nil 176 } 177 178 // InputFromGraphQL missing godoc 179 func (c *converter) InputFromGraphQL(in *graphql.WebhookInput) (*model.WebhookInput, error) { 180 if in == nil { 181 return nil, nil 182 } 183 184 auth, err := c.authConverter.InputFromGraphQL(in.Auth) 185 if err != nil { 186 return nil, errors.Wrap(err, "while converting Auth input") 187 } 188 189 var webhookMode *model.WebhookMode 190 if in.Mode != nil { 191 mode := model.WebhookMode(*in.Mode) 192 webhookMode = &mode 193 } 194 195 return &model.WebhookInput{ 196 Type: model.WebhookType(in.Type), 197 URL: in.URL, 198 Auth: auth, 199 Mode: webhookMode, 200 CorrelationIDKey: in.CorrelationIDKey, 201 RetryInterval: in.RetryInterval, 202 Timeout: in.Timeout, 203 URLTemplate: in.URLTemplate, 204 InputTemplate: in.InputTemplate, 205 HeaderTemplate: in.HeaderTemplate, 206 OutputTemplate: in.OutputTemplate, 207 StatusTemplate: in.StatusTemplate, 208 }, nil 209 } 210 211 // MultipleInputFromGraphQL missing godoc 212 func (c *converter) MultipleInputFromGraphQL(in []*graphql.WebhookInput) ([]*model.WebhookInput, error) { 213 inputs := make([]*model.WebhookInput, 0, len(in)) 214 for _, r := range in { 215 if r == nil { 216 continue 217 } 218 webhookIn, err := c.InputFromGraphQL(r) 219 if err != nil { 220 return nil, err 221 } 222 223 inputs = append(inputs, webhookIn) 224 } 225 226 return inputs, nil 227 } 228 229 // ToEntity missing godoc 230 func (c *converter) ToEntity(in *model.Webhook) (*Entity, error) { 231 optionalAuth, err := c.toAuthEntity(*in) 232 if err != nil { 233 return nil, err 234 } 235 236 var webhookMode sql.NullString 237 if in.Mode != nil { 238 webhookMode.String = string(*in.Mode) 239 webhookMode.Valid = true 240 } 241 242 var appID sql.NullString 243 var runtimeID sql.NullString 244 var appTemplateID sql.NullString 245 var intSystemID sql.NullString 246 var formationTemplateID sql.NullString 247 switch in.ObjectType { 248 case model.ApplicationWebhookReference: 249 appID = repo.NewValidNullableString(in.ObjectID) 250 case model.RuntimeWebhookReference: 251 runtimeID = repo.NewValidNullableString(in.ObjectID) 252 case model.ApplicationTemplateWebhookReference: 253 appTemplateID = repo.NewValidNullableString(in.ObjectID) 254 case model.IntegrationSystemWebhookReference: 255 intSystemID = repo.NewValidNullableString(in.ObjectID) 256 case model.FormationTemplateWebhookReference: 257 formationTemplateID = repo.NewValidNullableString(in.ObjectID) 258 } 259 260 return &Entity{ 261 ID: in.ID, 262 ApplicationID: appID, 263 ApplicationTemplateID: appTemplateID, 264 RuntimeID: runtimeID, 265 IntegrationSystemID: intSystemID, 266 FormationTemplateID: formationTemplateID, 267 CollectionIDKey: repo.NewNullableString(in.CorrelationIDKey), 268 Type: string(in.Type), 269 URL: repo.NewNullableString(in.URL), 270 Auth: optionalAuth, 271 Mode: webhookMode, 272 RetryInterval: repo.NewNullableInt(in.RetryInterval), 273 Timeout: repo.NewNullableInt(in.Timeout), 274 URLTemplate: repo.NewNullableString(in.URLTemplate), 275 InputTemplate: repo.NewNullableString(in.InputTemplate), 276 HeaderTemplate: repo.NewNullableString(in.HeaderTemplate), 277 OutputTemplate: repo.NewNullableString(in.OutputTemplate), 278 StatusTemplate: repo.NewNullableString(in.StatusTemplate), 279 CreatedAt: in.CreatedAt, 280 }, nil 281 } 282 283 func (c *converter) toAuthEntity(in model.Webhook) (sql.NullString, error) { 284 var optionalAuth sql.NullString 285 if in.Auth == nil { 286 return optionalAuth, nil 287 } 288 289 b, err := json.Marshal(in.Auth) 290 if err != nil { 291 return sql.NullString{}, errors.Wrap(err, "while marshalling Auth") 292 } 293 294 if err := optionalAuth.Scan(b); err != nil { 295 return sql.NullString{}, errors.Wrap(err, "while scanning optional Auth") 296 } 297 return optionalAuth, nil 298 } 299 300 // FromEntity missing godoc 301 func (c *converter) FromEntity(in *Entity) (*model.Webhook, error) { 302 auth, err := c.fromEntityAuth(*in) 303 if err != nil { 304 return nil, err 305 } 306 307 var webhookMode *model.WebhookMode 308 if in.Mode.Valid { 309 webhookModeStr := model.WebhookMode(in.Mode.String) 310 webhookMode = &webhookModeStr 311 } 312 313 objID, objType, err := c.objectReferenceFromEntity(*in) 314 if err != nil { 315 return nil, err 316 } 317 318 return &model.Webhook{ 319 ID: in.ID, 320 ObjectID: objID, 321 ObjectType: objType, 322 CorrelationIDKey: repo.StringPtrFromNullableString(in.CollectionIDKey), 323 Type: model.WebhookType(in.Type), 324 URL: repo.StringPtrFromNullableString(in.URL), 325 Auth: auth, 326 Mode: webhookMode, 327 RetryInterval: repo.IntPtrFromNullableInt(in.RetryInterval), 328 Timeout: repo.IntPtrFromNullableInt(in.Timeout), 329 URLTemplate: repo.StringPtrFromNullableString(in.URLTemplate), 330 InputTemplate: repo.StringPtrFromNullableString(in.InputTemplate), 331 HeaderTemplate: repo.StringPtrFromNullableString(in.HeaderTemplate), 332 OutputTemplate: repo.StringPtrFromNullableString(in.OutputTemplate), 333 StatusTemplate: repo.StringPtrFromNullableString(in.StatusTemplate), 334 CreatedAt: in.CreatedAt, 335 }, nil 336 } 337 338 func (c *converter) fromEntityAuth(in Entity) (*model.Auth, error) { 339 if !in.Auth.Valid { 340 return nil, nil 341 } 342 343 auth := &model.Auth{} 344 val, err := in.Auth.Value() 345 if err != nil { 346 return nil, errors.Wrap(err, "while reading Auth from Entity") 347 } 348 349 b, ok := val.(string) 350 if !ok { 351 return nil, apperrors.NewInternalError("Auth should be slice of bytes") 352 } 353 if err := json.Unmarshal([]byte(b), auth); err != nil { 354 return nil, errors.Wrap(err, "while unmarshaling Auth") 355 } 356 357 return auth, nil 358 } 359 360 func (c *converter) objectReferenceFromEntity(in Entity) (string, model.WebhookReferenceObjectType, error) { 361 if in.ApplicationID.Valid { 362 return in.ApplicationID.String, model.ApplicationWebhookReference, nil 363 } 364 365 if in.RuntimeID.Valid { 366 return in.RuntimeID.String, model.RuntimeWebhookReference, nil 367 } 368 369 if in.ApplicationTemplateID.Valid { 370 return in.ApplicationTemplateID.String, model.ApplicationTemplateWebhookReference, nil 371 } 372 373 if in.IntegrationSystemID.Valid { 374 return in.IntegrationSystemID.String, model.IntegrationSystemWebhookReference, nil 375 } 376 377 if in.FormationTemplateID.Valid { 378 return in.FormationTemplateID.String, model.FormationTemplateWebhookReference, nil 379 } 380 381 return "", "", fmt.Errorf("incorrect Object Reference ID and its type for Entity with ID '%s'", in.ID) 382 } 383 384 func timePtrToTimestampPtr(time *time.Time) *graphql.Timestamp { 385 if time == nil { 386 return nil 387 } 388 389 t := graphql.Timestamp(*time) 390 return &t 391 }