github.com/Axway/agent-sdk@v1.1.101/pkg/transaction/logeventbuilder.go (about) 1 package transaction 2 3 import ( 4 "errors" 5 "reflect" 6 "time" 7 8 "github.com/Axway/agent-sdk/pkg/agent" 9 "github.com/Axway/agent-sdk/pkg/traceability/redaction" 10 "github.com/Axway/agent-sdk/pkg/transaction/models" 11 "github.com/Axway/agent-sdk/pkg/util" 12 ) 13 14 const defaultAPICDeployment = "prod" 15 16 // IsValid - Validator for TxEventStatus 17 func (s TxEventStatus) IsValid() error { 18 switch s { 19 case TxEventStatusPass, TxEventStatusFail: 20 return nil 21 } 22 return errors.New("invalid transaction event status") 23 } 24 25 // IsValid - Validator for TxSummaryStatus 26 func (s TxSummaryStatus) IsValid() error { 27 switch s { 28 case TxSummaryStatusSuccess, TxSummaryStatusFailure, TxSummaryStatusException, TxSummaryStatusUnknown: 29 return nil 30 } 31 return errors.New("invalid transaction summary status") 32 } 33 34 // EventBuilder - Interface to build the log event of type transaction event 35 type EventBuilder interface { 36 SetTimestamp(timestamp int64) EventBuilder 37 SetTransactionID(transactionID string) EventBuilder 38 SetAPICDeployment(apicDeployment string) EventBuilder 39 SetEnvironmentName(environmentName string) EventBuilder 40 SetEnvironmentID(environmentID string) EventBuilder 41 SetTenantID(tenantID string) EventBuilder 42 SetTrcbltPartitionID(trcbltPartitionID string) EventBuilder 43 SetTargetPath(targetPath string) EventBuilder 44 SetResourcePath(resourcePath string) EventBuilder 45 46 SetID(id string) EventBuilder 47 SetParentID(parentID string) EventBuilder 48 SetSource(source string) EventBuilder 49 SetDestination(destination string) EventBuilder 50 SetDuration(duration int) EventBuilder 51 SetDirection(direction string) EventBuilder 52 SetStatus(status TxEventStatus) EventBuilder 53 SetProtocolDetail(protocolDetail interface{}) EventBuilder 54 SetRedactionConfig(config redaction.Redactions) EventBuilder 55 56 Build() (*LogEvent, error) 57 } 58 59 type transactionEventBuilder struct { 60 EventBuilder 61 err error 62 cfgTenantID string 63 cfgAPICDeployment string 64 cfgEnvironmentName string 65 cfgEnvironmentID string 66 logEvent *LogEvent 67 redactionConfig redaction.Redactions 68 } 69 70 // SummaryBuilder - Interface to build the log event of type transaction summary 71 type SummaryBuilder interface { 72 SetTimestamp(timestamp int64) SummaryBuilder 73 SetTransactionID(transactionID string) SummaryBuilder 74 SetAPICDeployment(apicDeployment string) SummaryBuilder 75 SetEnvironmentName(environmentName string) SummaryBuilder 76 SetEnvironmentID(environmentID string) SummaryBuilder 77 SetTenantID(tenantID string) SummaryBuilder 78 SetTrcbltPartitionID(trcbltPartitionID string) SummaryBuilder 79 SetTargetPath(targetPath string) SummaryBuilder 80 SetResourcePath(resourcePath string) SummaryBuilder 81 82 SetStatus(status TxSummaryStatus, statusDetail string) SummaryBuilder 83 SetDuration(duration int) SummaryBuilder 84 SetApplication(appID, appName string) SummaryBuilder 85 SetProduct(id, name, version string) SummaryBuilder 86 SetTeam(teamID string) SummaryBuilder 87 SetProxy(proxyID, proxyName string, proxyRevision int) SummaryBuilder 88 SetProxyWithStage(proxyID, proxyName, proxyStage string, proxyRevision int) SummaryBuilder 89 SetProxyWithStageVersion(proxyID, proxyName, proxyStage, proxyVersion string, proxyRevision int) SummaryBuilder 90 SetRunTime(runtimeID, runtimeName string) SummaryBuilder 91 SetEntryPoint(entryPointType, method, path, host string) SummaryBuilder 92 SetIsInMetricEvent(isInMetricEvent bool) SummaryBuilder 93 SetRedactionConfig(config redaction.Redactions) SummaryBuilder 94 Build() (*LogEvent, error) 95 } 96 97 type transactionSummaryBuilder struct { 98 SummaryBuilder 99 err error 100 cfgTenantID string 101 cfgAPICDeployment string 102 cfgEnvironmentName string 103 cfgEnvironmentID string 104 logEvent *LogEvent 105 redactionConfig redaction.Redactions 106 } 107 108 // NewTransactionEventBuilder - Creates a new log event builder 109 func NewTransactionEventBuilder() EventBuilder { 110 txEventBuilder := &transactionEventBuilder{ 111 logEvent: &LogEvent{ 112 Version: "1.0", 113 Stamp: time.Now().Unix(), 114 Type: TypeTransactionEvent, 115 TransactionEvent: &Event{}, 116 TransactionSummary: nil, 117 APICDeployment: defaultAPICDeployment, 118 }, 119 } 120 121 cfg := agent.GetCentralConfig() 122 // Check interface and value are not nil 123 if cfg != nil && !reflect.ValueOf(cfg).IsNil() { 124 txEventBuilder.logEvent.TenantID = cfg.GetTenantID() 125 txEventBuilder.logEvent.EnvironmentName = cfg.GetEnvironmentName() 126 txEventBuilder.logEvent.EnvironmentID = cfg.GetEnvironmentID() 127 txEventBuilder.logEvent.APICDeployment = cfg.GetAPICDeployment() 128 } 129 return txEventBuilder 130 } 131 132 // NewTransactionSummaryBuilder - Creates a new log event builder 133 func NewTransactionSummaryBuilder() SummaryBuilder { 134 txSummaryBuilder := &transactionSummaryBuilder{ 135 logEvent: &LogEvent{ 136 Version: "1.0", 137 Stamp: time.Now().Unix(), 138 Type: TypeTransactionSummary, 139 TransactionEvent: nil, 140 TransactionSummary: &Summary{}, 141 APICDeployment: defaultAPICDeployment, 142 }, 143 } 144 145 cfg := agent.GetCentralConfig() 146 // Check interface and value are not nil 147 if cfg != nil && !reflect.ValueOf(cfg).IsNil() { 148 txSummaryBuilder.logEvent.TenantID = cfg.GetTenantID() 149 txSummaryBuilder.logEvent.EnvironmentName = cfg.GetEnvironmentName() 150 txSummaryBuilder.logEvent.EnvironmentID = cfg.GetEnvironmentID() 151 txSummaryBuilder.logEvent.APICDeployment = cfg.GetAPICDeployment() 152 txSummaryBuilder.logEvent.TransactionSummary.IsInMetricEvent = 153 cfg.GetMetricReportingConfig().CanPublish() 154 } 155 return txSummaryBuilder 156 } 157 158 func (b *transactionEventBuilder) SetTimestamp(timestamp int64) EventBuilder { 159 if b.err != nil { 160 return b 161 } 162 b.logEvent.Stamp = timestamp 163 return b 164 } 165 166 func (b *transactionEventBuilder) SetTransactionID(transactionID string) EventBuilder { 167 if b.err != nil { 168 return b 169 } 170 b.logEvent.TransactionID = transactionID 171 return b 172 } 173 174 func (b *transactionEventBuilder) SetAPICDeployment(apicDeployment string) EventBuilder { 175 if b.err != nil { 176 return b 177 } 178 b.logEvent.APICDeployment = apicDeployment 179 return b 180 } 181 182 func (b *transactionEventBuilder) SetEnvironmentName(environmentName string) EventBuilder { 183 if b.err != nil { 184 return b 185 } 186 b.logEvent.EnvironmentName = environmentName 187 return b 188 } 189 190 func (b *transactionEventBuilder) SetEnvironmentID(environmentID string) EventBuilder { 191 if b.err != nil { 192 return b 193 } 194 b.logEvent.EnvironmentID = environmentID 195 return b 196 } 197 198 func (b *transactionEventBuilder) SetTenantID(tenantID string) EventBuilder { 199 if b.err != nil { 200 return b 201 } 202 b.logEvent.TenantID = tenantID 203 return b 204 } 205 206 func (b *transactionEventBuilder) SetTrcbltPartitionID(trcbltPartitionID string) EventBuilder { 207 if b.err != nil { 208 return b 209 } 210 b.logEvent.TrcbltPartitionID = trcbltPartitionID 211 return b 212 } 213 214 func (b *transactionEventBuilder) SetTargetPath(targetPath string) EventBuilder { 215 if b.err != nil { 216 return b 217 } 218 b.logEvent.TargetPath = targetPath 219 return b 220 } 221 222 func (b *transactionEventBuilder) SetResourcePath(resourcePath string) EventBuilder { 223 if b.err != nil { 224 return b 225 } 226 b.logEvent.ResourcePath = resourcePath 227 return b 228 } 229 230 func (b *transactionEventBuilder) SetID(id string) EventBuilder { 231 if b.err != nil { 232 return b 233 } 234 b.logEvent.TransactionEvent.ID = id 235 return b 236 } 237 238 func (b *transactionEventBuilder) SetParentID(parentID string) EventBuilder { 239 if b.err != nil { 240 return b 241 } 242 b.logEvent.TransactionEvent.ParentID = parentID 243 return b 244 } 245 246 func (b *transactionEventBuilder) SetSource(source string) EventBuilder { 247 if b.err != nil { 248 return b 249 } 250 b.logEvent.TransactionEvent.Source = source 251 return b 252 } 253 254 func (b *transactionEventBuilder) SetDestination(destination string) EventBuilder { 255 if b.err != nil { 256 return b 257 } 258 b.logEvent.TransactionEvent.Destination = destination 259 return b 260 } 261 262 func (b *transactionEventBuilder) SetDuration(duration int) EventBuilder { 263 if b.err != nil { 264 return b 265 } 266 b.logEvent.TransactionEvent.Duration = duration 267 return b 268 } 269 270 func (b *transactionEventBuilder) SetDirection(direction string) EventBuilder { 271 if b.err != nil { 272 return b 273 } 274 b.logEvent.TransactionEvent.Direction = direction 275 return b 276 } 277 278 func (b *transactionEventBuilder) SetStatus(status TxEventStatus) EventBuilder { 279 if b.err != nil { 280 return b 281 } 282 err := status.IsValid() 283 if err != nil { 284 b.err = err 285 return b 286 } 287 b.logEvent.TransactionEvent.Status = string(status) 288 return b 289 } 290 291 func (b *transactionEventBuilder) SetProtocolDetail(protocolDetail interface{}) EventBuilder { 292 if b.err != nil { 293 return b 294 } 295 _, ok := protocolDetail.(*Protocol) 296 if !ok { 297 _, ok = protocolDetail.(*JMSProtocol) 298 } 299 if ok { 300 b.logEvent.TransactionEvent.Protocol = protocolDetail 301 } else { 302 b.err = errors.New("unsupported protocol type") 303 } 304 return b 305 } 306 307 func (b *transactionEventBuilder) SetRedactionConfig(config redaction.Redactions) EventBuilder { 308 if b.err != nil { 309 return b 310 } 311 b.redactionConfig = config 312 return b 313 } 314 315 func (b *transactionEventBuilder) Build() (*LogEvent, error) { 316 if b.err != nil { 317 return nil, b.err 318 } 319 320 // Set Target Path 321 if b.redactionConfig == nil { 322 b.logEvent.TargetPath, _ = redaction.URIRedaction(b.logEvent.TargetPath) 323 } else { 324 b.logEvent.TargetPath, _ = b.redactionConfig.URIRedaction(b.logEvent.TargetPath) 325 } 326 327 //Set Resource Path 328 if b.redactionConfig == nil { 329 b.logEvent.ResourcePath, _ = redaction.URIRedaction(b.logEvent.ResourcePath) 330 } else { 331 b.logEvent.ResourcePath, _ = b.redactionConfig.URIRedaction(b.logEvent.ResourcePath) 332 } 333 334 if b.logEvent.TrcbltPartitionID == "" { 335 b.logEvent.TrcbltPartitionID = b.logEvent.TenantID 336 } 337 338 err := b.validateLogEvent() 339 if err != nil { 340 return nil, err 341 } 342 343 return b.logEvent, nil 344 } 345 346 func (b *transactionEventBuilder) validateLogEvent() error { 347 if agent.GetCentralConfig() == nil { 348 return nil 349 } 350 if util.IsNotTest() && agent.GetCentralConfig().GetUsageReportingConfig().IsOfflineMode() { 351 // Do not need this information in offline mode 352 return nil 353 } 354 355 if b.logEvent.TenantID == "" { 356 return errors.New("tenant ID property not set in transaction event") 357 } 358 359 if b.logEvent.EnvironmentID == "" { 360 return errors.New("environment ID property are not set in transaction event") 361 } 362 363 if b.logEvent.TransactionEvent.ID == "" { 364 return errors.New("id property not set in transaction event") 365 } 366 367 if b.logEvent.TransactionEvent.Direction == "" { 368 return errors.New("direction property not set in transaction event") 369 } 370 371 if b.logEvent.TransactionEvent.Status == "" { 372 return errors.New("status property not set in transaction event") 373 } 374 375 if b.logEvent.TransactionEvent.Protocol == nil { 376 return errors.New("protocol details not set in transaction event") 377 } 378 return nil 379 } 380 381 func (b *transactionSummaryBuilder) SetTimestamp(timestamp int64) SummaryBuilder { 382 if b.err != nil { 383 return b 384 } 385 b.logEvent.Stamp = timestamp 386 return b 387 } 388 389 func (b *transactionSummaryBuilder) SetTransactionID(transactionID string) SummaryBuilder { 390 if b.err != nil { 391 return b 392 } 393 b.logEvent.TransactionID = transactionID 394 return b 395 } 396 397 func (b *transactionSummaryBuilder) SetAPICDeployment(apicDeployment string) SummaryBuilder { 398 if b.err != nil { 399 return b 400 } 401 b.logEvent.APICDeployment = apicDeployment 402 return b 403 } 404 405 func (b *transactionSummaryBuilder) SetEnvironmentName(environmentName string) SummaryBuilder { 406 if b.err != nil { 407 return b 408 } 409 b.logEvent.EnvironmentName = environmentName 410 return b 411 } 412 413 func (b *transactionSummaryBuilder) SetEnvironmentID(environmentID string) SummaryBuilder { 414 if b.err != nil { 415 return b 416 } 417 b.logEvent.EnvironmentID = environmentID 418 return b 419 } 420 421 func (b *transactionSummaryBuilder) SetTenantID(tenantID string) SummaryBuilder { 422 if b.err != nil { 423 return b 424 } 425 b.logEvent.TenantID = tenantID 426 return b 427 } 428 429 func (b *transactionSummaryBuilder) SetTrcbltPartitionID(trcbltPartitionID string) SummaryBuilder { 430 if b.err != nil { 431 return b 432 } 433 b.logEvent.TrcbltPartitionID = trcbltPartitionID 434 return b 435 } 436 437 func (b *transactionSummaryBuilder) SetTargetPath(targetPath string) SummaryBuilder { 438 if b.err != nil { 439 return b 440 } 441 b.logEvent.TargetPath = targetPath 442 return b 443 } 444 445 func (b *transactionSummaryBuilder) SetResourcePath(resourcePath string) SummaryBuilder { 446 if b.err != nil { 447 return b 448 } 449 b.logEvent.ResourcePath = resourcePath 450 return b 451 } 452 453 func (b *transactionSummaryBuilder) SetStatus(status TxSummaryStatus, statusDetail string) SummaryBuilder { 454 if b.err != nil { 455 return b 456 } 457 err := status.IsValid() 458 if err != nil { 459 b.err = err 460 return b 461 } 462 b.logEvent.TransactionSummary.Status = string(status) 463 b.logEvent.TransactionSummary.StatusDetail = statusDetail 464 return b 465 } 466 467 func (b *transactionSummaryBuilder) SetDuration(duration int) SummaryBuilder { 468 if b.err != nil { 469 return b 470 } 471 b.logEvent.TransactionSummary.Duration = duration 472 return b 473 } 474 475 func (b *transactionSummaryBuilder) SetApplication(appID, appName string) SummaryBuilder { 476 if b.err != nil { 477 return b 478 } 479 b.logEvent.TransactionSummary.Application = &Application{ 480 ID: appID, 481 Name: appName, 482 } 483 484 return b 485 } 486 487 // Currently, no one is setting Product for transaction summary builder, but leaving function signature as is for now 488 func (b *transactionSummaryBuilder) SetProduct(id, name, versionID string) SummaryBuilder { 489 if b.err != nil { 490 return b 491 } 492 b.logEvent.TransactionSummary.Product = &models.Product{ 493 ID: id, 494 Name: name, 495 VersionID: versionID, 496 } 497 498 return b 499 } 500 501 func (b *transactionSummaryBuilder) SetTeam(teamID string) SummaryBuilder { 502 if b.err != nil { 503 return b 504 } 505 b.logEvent.TransactionSummary.Team = &Team{ 506 ID: teamID, 507 } 508 return b 509 } 510 511 func (b *transactionSummaryBuilder) SetProxy(proxyID, proxyName string, proxyRevision int) SummaryBuilder { 512 return b.SetProxyWithStage(proxyID, proxyName, "", proxyRevision) 513 } 514 515 func (b *transactionSummaryBuilder) SetProxyWithStage(proxyID, proxyName, proxyStage string, proxyRevision int) SummaryBuilder { 516 return b.SetProxyWithStageVersion(proxyID, proxyName, proxyStage, "", proxyRevision) 517 } 518 519 func (b *transactionSummaryBuilder) SetProxyWithStageVersion(proxyID, proxyName, proxyStage, proxyVersion string, proxyRevision int) SummaryBuilder { 520 if b.err != nil { 521 return b 522 } 523 if proxyID == "" { 524 proxyID = "unknown" 525 } 526 b.logEvent.TransactionSummary.Proxy = &Proxy{ 527 ID: proxyID, 528 Revision: proxyRevision, 529 Name: proxyName, 530 Stage: proxyStage, 531 Version: proxyVersion, 532 } 533 return b 534 } 535 536 func (b *transactionSummaryBuilder) SetRunTime(runtimeID, runtimeName string) SummaryBuilder { 537 if b.err != nil { 538 return b 539 } 540 b.logEvent.TransactionSummary.Runtime = &Runtime{ 541 ID: runtimeID, 542 Name: runtimeName, 543 } 544 return b 545 } 546 547 func (b *transactionSummaryBuilder) SetEntryPoint(entryPointType, method, path, host string) SummaryBuilder { 548 if b.err != nil { 549 return b 550 } 551 552 b.logEvent.TransactionSummary.EntryPoint = &EntryPoint{ 553 Type: entryPointType, 554 Method: method, 555 Path: path, 556 Host: host, 557 } 558 return b 559 } 560 561 func (b *transactionSummaryBuilder) SetIsInMetricEvent(isInMetricEvent bool) SummaryBuilder { 562 if b.err != nil { 563 return b 564 } 565 566 b.logEvent.TransactionSummary.IsInMetricEvent = isInMetricEvent 567 568 return b 569 } 570 571 func (b *transactionSummaryBuilder) SetRedactionConfig(config redaction.Redactions) SummaryBuilder { 572 if b.err != nil { 573 return b 574 } 575 b.redactionConfig = config 576 return b 577 } 578 579 func (b *transactionSummaryBuilder) Build() (*LogEvent, error) { 580 if b.err != nil { 581 return nil, b.err 582 } 583 584 // Set Target Path 585 if b.redactionConfig == nil { 586 b.logEvent.TargetPath, b.err = redaction.URIRedaction(b.logEvent.TargetPath) 587 } else { 588 b.logEvent.TargetPath, b.err = b.redactionConfig.URIRedaction(b.logEvent.TargetPath) 589 } 590 if b.err != nil { 591 return nil, b.err 592 } 593 594 //Set Resource Path 595 if b.redactionConfig == nil { 596 b.logEvent.ResourcePath, b.err = redaction.URIRedaction(b.logEvent.ResourcePath) 597 } else { 598 b.logEvent.ResourcePath, b.err = b.redactionConfig.URIRedaction(b.logEvent.ResourcePath) 599 } 600 if b.err != nil { 601 return nil, b.err 602 } 603 604 // Set redacted path in EntryPoint 605 if b.logEvent.TransactionSummary.EntryPoint == nil { 606 return nil, errors.New("transaction entry point details are not set in transaction summary event") 607 } 608 if b.redactionConfig == nil { 609 b.logEvent.TransactionSummary.EntryPoint.Path, b.err = redaction.URIRedaction(b.logEvent.TransactionSummary.EntryPoint.Path) 610 } else { 611 b.logEvent.TransactionSummary.EntryPoint.Path, b.err = b.redactionConfig.URIRedaction(b.logEvent.TransactionSummary.EntryPoint.Path) 612 } 613 if b.err != nil { 614 return nil, b.err 615 } 616 617 if b.logEvent.TrcbltPartitionID == "" { 618 b.logEvent.TrcbltPartitionID = b.logEvent.TenantID 619 } 620 621 if b.logEvent.TransactionSummary.Proxy == nil { 622 b.logEvent.TransactionSummary.Proxy = &Proxy{ 623 ID: "unknown", 624 } 625 } 626 627 if b.logEvent.TransactionSummary.Proxy.Revision == 0 { 628 b.logEvent.TransactionSummary.Proxy.Revision = 1 629 } 630 631 err := b.validateLogEvent() 632 if err != nil { 633 return nil, err 634 } 635 return b.logEvent, b.err 636 } 637 638 func (b *transactionSummaryBuilder) validateLogEvent() error { 639 if agent.GetCentralConfig() == nil { 640 return nil 641 } 642 643 if util.IsNotTest() && agent.GetCentralConfig().GetUsageReportingConfig().IsOfflineMode() { 644 // Do not need this information in offline mode 645 return nil 646 } 647 648 if b.logEvent.TenantID == "" { 649 return errors.New("tenant ID property not set in transaction summary event") 650 } 651 652 if b.logEvent.EnvironmentID == "" { 653 return errors.New("environment ID property are not set in transaction summary event") 654 } 655 656 if b.logEvent.TransactionSummary.Status == "" { 657 return errors.New("status property not set in transaction summary event") 658 } 659 660 if b.logEvent.TransactionSummary.Product != nil && b.logEvent.TransactionSummary.Product.ID == "" { 661 return errors.New("product ID property not set in transaction summary event") 662 } 663 return nil 664 }