github.com/argoproj/argo-events@v1.9.1/sensors/triggers/nats/nats.go (about)

     1  /*
     2  Copyright 2018 BlackRock, Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package nats
    17  
    18  import (
    19  	"context"
    20  	"encoding/json"
    21  	"fmt"
    22  
    23  	natslib "github.com/nats-io/nats.go"
    24  	"go.uber.org/zap"
    25  
    26  	"github.com/argoproj/argo-events/common"
    27  	"github.com/argoproj/argo-events/common/logging"
    28  	apicommon "github.com/argoproj/argo-events/pkg/apis/common"
    29  	"github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1"
    30  	"github.com/argoproj/argo-events/sensors/triggers"
    31  )
    32  
    33  // NATSTrigger holds the context of the NATS trigger.
    34  type NATSTrigger struct {
    35  	// Sensor object.
    36  	Sensor *v1alpha1.Sensor
    37  	// Trigger reference.
    38  	Trigger *v1alpha1.Trigger
    39  	// Conn refers to the NATS client connection.
    40  	Conn *natslib.Conn
    41  	// Logger to log stuff.
    42  	Logger *zap.SugaredLogger
    43  }
    44  
    45  // NewNATSTrigger returns new nats trigger.
    46  func NewNATSTrigger(sensor *v1alpha1.Sensor, trigger *v1alpha1.Trigger, natsConnections common.StringKeyedMap[*natslib.Conn], logger *zap.SugaredLogger) (*NATSTrigger, error) {
    47  	natstrigger := trigger.Template.NATS
    48  
    49  	conn, ok := natsConnections.Load(trigger.Template.Name)
    50  	if !ok {
    51  		var err error
    52  		opts := natslib.GetDefaultOptions()
    53  		opts.Url = natstrigger.URL
    54  
    55  		if natstrigger.TLS != nil {
    56  			tlsConfig, err := common.GetTLSConfig(natstrigger.TLS)
    57  			if err != nil {
    58  				return nil, fmt.Errorf("failed to get the tls configuration, %w", err)
    59  			}
    60  			tlsConfig.InsecureSkipVerify = true
    61  			opts.Secure = true
    62  			opts.TLSConfig = tlsConfig
    63  		}
    64  
    65  		conn, err = opts.Connect()
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  
    70  		natsConnections.Store(trigger.Template.Name, conn)
    71  	}
    72  
    73  	return &NATSTrigger{
    74  		Sensor:  sensor,
    75  		Trigger: trigger,
    76  		Conn:    conn,
    77  		Logger:  logger.With(logging.LabelTriggerType, apicommon.NATSTrigger),
    78  	}, nil
    79  }
    80  
    81  // GetTriggerType returns the type of the trigger
    82  func (t *NATSTrigger) GetTriggerType() apicommon.TriggerType {
    83  	return apicommon.NATSTrigger
    84  }
    85  
    86  // FetchResource fetches the trigger. As the NATS trigger is simply a NATS client, there
    87  // is no need to fetch any resource from external source
    88  func (t *NATSTrigger) FetchResource(ctx context.Context) (interface{}, error) {
    89  	return t.Trigger.Template.NATS, nil
    90  }
    91  
    92  // ApplyResourceParameters applies parameters to the trigger resource
    93  func (t *NATSTrigger) ApplyResourceParameters(events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) {
    94  	fetchedResource, ok := resource.(*v1alpha1.NATSTrigger)
    95  	if !ok {
    96  		return nil, fmt.Errorf("failed to interpret the fetched trigger resource")
    97  	}
    98  
    99  	resourceBytes, err := json.Marshal(fetchedResource)
   100  	if err != nil {
   101  		return nil, fmt.Errorf("failed to marshal the nats trigger resource, %w", err)
   102  	}
   103  	parameters := fetchedResource.Parameters
   104  	if parameters != nil {
   105  		updatedResourceBytes, err := triggers.ApplyParams(resourceBytes, parameters, events)
   106  		if err != nil {
   107  			return nil, err
   108  		}
   109  		var ht *v1alpha1.NATSTrigger
   110  		if err := json.Unmarshal(updatedResourceBytes, &ht); err != nil {
   111  			return nil, fmt.Errorf("failed to unmarshal the updated nats trigger resource after applying resource parameters, %w", err)
   112  		}
   113  		return ht, nil
   114  	}
   115  	return resource, nil
   116  }
   117  
   118  // Execute executes the trigger
   119  func (t *NATSTrigger) Execute(ctx context.Context, events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) {
   120  	trigger, ok := resource.(*v1alpha1.NATSTrigger)
   121  	if !ok {
   122  		return nil, fmt.Errorf("failed to interpret the trigger resource")
   123  	}
   124  
   125  	if trigger.Payload == nil {
   126  		return nil, fmt.Errorf("payload parameters are not specified")
   127  	}
   128  
   129  	payload, err := triggers.ConstructPayload(events, trigger.Payload)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  
   134  	if err := t.Conn.Publish(t.Trigger.Template.NATS.Subject, payload); err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	return nil, nil
   139  }
   140  
   141  // ApplyPolicy applies policy on the trigger
   142  func (t *NATSTrigger) ApplyPolicy(ctx context.Context, resource interface{}) error {
   143  	return nil
   144  }