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  }