Пример #1
0
        protected virtual void SubscribeToTopic(ISession session, string topicName, string clientName, string subscriptionQueueName = null, SubscriptionOptions options = null)
        {
            if (string.IsNullOrEmpty(subscriptionQueueName))
            {
                subscriptionQueueName = $"{clientName}_{typeof(TContent)}";
            }

            this.subscriptionQueueName = subscriptionQueueName;

            log.Debug("Subscribing to topic {0} on {1} endpoint named {2}", topicName, options.Durable ? "durable" : "non-durable", subscriptionQueueName);

            ITopicEndpoint endpoint = null;

            if (options.Durable)
            {
                endpoint = ContextFactory.Instance.CreateDurableTopicEndpointEx(subscriptionQueueName);

                session.Provision(endpoint, new EndpointProperties
                {
                    DiscardBehavior = EndpointProperties.EndpointDiscardBehavior.NotifySenderOn,
                    AccessType      = options.Exclusive ? EndpointProperties.EndpointAccessType.Exclusive : EndpointProperties.EndpointAccessType.NonExclusive
                }, ProvisionFlag.WaitForConfirm | ProvisionFlag.IgnoreErrorIfEndpointAlreadyExists, null);
            }
            else
            {
                endpoint = session.CreateNonDurableTopicEndpoint(subscriptionQueueName);
            }

            try
            {
                this.flow = session.CreateFlow(
                    new FlowProperties {
                    AckMode = (options?.SubscriptionType ?? SubscriptionType.PeekAndLock) == SubscriptionType.PeekAndLock ? MessageAckMode.ClientAck : MessageAckMode.AutoAck
                },
                    endpoint,
                    ContextFactory.Instance.CreateTopic(topicName),
                    HandleMessage,
                    FlowEventHandler);

                flow.Start();

                this.workerThread = new Thread(new ThreadStart(RunMessageLoop));
                workerThread.Start();
            }
            catch (global::SolaceSystems.Solclient.Messaging.OperationErrorException ex)
            {
                log.Error($"Failed to subscribe to topic. ErrorInfo: {ex.ErrorInfo}");
                throw;
            }
        }
Пример #2
0
        /// <summary>
        /// @see IState#Handle .
        /// </summary>
        /// <param name="executor"></param>
        /// <returns></returns>
        public override FlowExecutionStatus Handle(IFlowExecutor executor)
        {
            ICollection <Task <FlowExecution> > tasks = new List <Task <FlowExecution> >();

            foreach (IFlow flow in _flows)
            {
                IFlow aFlow = flow;
                Task <FlowExecution> task = new Task <FlowExecution>(() => aFlow.Start(executor));
                tasks.Add(task);
                try
                {
                    _taskExecutor.Execute(task);
                }
                catch (TaskRejectedException)
                {
                    throw new FlowExecutionException("TaskExecutor rejected task for flow=" + flow.GetName());
                }
            }
            ICollection <FlowExecution> results = tasks.Select(task => task.Result).ToList();

            return(DoAggregation(results, executor));
        }
Пример #3
0
 /// <summary>
 /// @see IState#Handle .
 /// </summary>
 /// <param name="executor"></param>
 /// <returns></returns>
 public override FlowExecutionStatus Handle(IFlowExecutor executor)
 {
     return(_flow.Start(executor).Status);
 }
Пример #4
0
        void Run(IContext context, string host)
        {
            // Validate parameters
            if (context == null)
            {
                throw new ArgumentException("Solace Systems API context Router must be not null.", "context");
            }
            if (string.IsNullOrWhiteSpace(host))
            {
                throw new ArgumentException("Solace Messaging Router host name must be non-empty.", "host");
            }
            if (string.IsNullOrWhiteSpace(VPNName))
            {
                throw new InvalidOperationException("VPN name must be non-empty.");
            }
            if (string.IsNullOrWhiteSpace(UserName))
            {
                throw new InvalidOperationException("Client username must be non-empty.");
            }

            // Create session properties
            SessionProperties sessionProps = new SessionProperties()
            {
                Host             = host,
                VPNName          = VPNName,
                UserName         = UserName,
                ReconnectRetries = DefaultReconnectRetries
            };

            // Connect to the Solace messaging router
            Console.WriteLine("Connecting as {0}@{1} on {2}...", UserName, VPNName, host);
            Session = context.CreateSession(sessionProps, null, null);
            ReturnCode returnCode = Session.Connect();

            if (returnCode == ReturnCode.SOLCLIENT_OK)
            {
                Console.WriteLine("Session successfully connected.");

                // Provision the queue
                string queueName = "Q/tutorial";
                Console.WriteLine("Attempting to provision the queue '{0}'...", queueName);

                // Set queue permissions to "consume" and access-type to "exclusive"
                EndpointProperties endpointProps = new EndpointProperties()
                {
                    Permission = EndpointProperties.EndpointPermission.Consume,
                    AccessType = EndpointProperties.EndpointAccessType.Exclusive
                };
                // Create the queue
                Queue = ContextFactory.Instance.CreateQueue(queueName);

                // Provision it, and do not fail if it already exists
                Session.Provision(Queue, endpointProps,
                                  ProvisionFlag.IgnoreErrorIfEndpointAlreadyExists & ProvisionFlag.WaitForConfirm, null);
                Console.WriteLine("Queue '{0}' has been created and provisioned.", queueName);

                // Create and start flow to the newly provisioned queue
                // NOTICE HandleMessageEvent as the message event handler
                // and HandleFlowEvent as the flow event handler
                Flow = Session.CreateFlow(new FlowProperties()
                {
                    AckMode = MessageAckMode.ClientAck
                },
                                          Queue, null, HandleMessageEvent, HandleFlowEvent);
                Flow.Start();
                Console.WriteLine("Waiting for a message in the queue '{0}'...", queueName);

                WaitEventWaitHandle.WaitOne();
            }
            else
            {
                Console.WriteLine("Error connecting, return code: {0}", returnCode);
            }
        }
Пример #5
0
        private void SubscribeAndSendMessage(ISession session)
        {
            // Provision the queue
            string queueName = "Q/tutorial/topicToQueueMapping";

            Console.WriteLine("Attempting to provision the queue '{0}'...", queueName);

            // Create the queue
            using (IQueue queue = ContextFactory.Instance.CreateQueue(queueName))
            {
                // Set queue permissions to "consume" and access-type to "exclusive"
                EndpointProperties endpointProps = new EndpointProperties()
                {
                    Permission = EndpointProperties.EndpointPermission.Consume,
                    AccessType = EndpointProperties.EndpointAccessType.Exclusive,
                };
                // Provision it, and do not fail if it already exists
                session.Provision(queue, endpointProps,
                                  ProvisionFlag.IgnoreErrorIfEndpointAlreadyExists | ProvisionFlag.WaitForConfirm, null);
                Console.WriteLine("Queue '{0}' has been created and provisioned.", queueName);

                // Add subscription to the topic mapped to the queue
                ITopic tutorialTopic = ContextFactory.Instance.CreateTopic("T/mapped/topic/sample");
                session.Subscribe(queue, tutorialTopic, SubscribeFlag.WaitForConfirm, null);

                // Create the message
                using (IMessage message = ContextFactory.Instance.CreateMessage())
                {
                    // Message's destination is the queue topic and the message is persistent
                    message.Destination  = tutorialTopic;
                    message.DeliveryMode = MessageDeliveryMode.Persistent;

                    // Send it to the mapped topic a few times with different content
                    for (int i = 0; i < TotalMessages; i++)
                    {
                        // Create the message content as a binary attachment
                        message.BinaryAttachment = Encoding.ASCII.GetBytes(
                            string.Format("Topic to Queue Mapping Tutorial! Message ID: {0}", i));

                        // Send the message to the queue on the Solace messaging router
                        Console.WriteLine("Sending message ID {0} to topic '{1}' mapped to queue '{2}'...",
                                          i, tutorialTopic.Name, queueName);
                        ReturnCode returnCode = session.Send(message);
                        if (returnCode == ReturnCode.SOLCLIENT_OK)
                        {
                            Console.WriteLine("Done.");
                        }
                        else
                        {
                            Console.WriteLine("Sending failed, return code: {0}", returnCode);
                        }
                    }
                }
                Console.WriteLine("{0} messages sent. Processing replies.", TotalMessages);

                // Create and start flow to the newly provisioned queue
                // NOTICE HandleMessageEvent as the message event handler
                // and HandleFlowEvent as the flow event handler
                Flow = session.CreateFlow(new FlowProperties()
                {
                    AckMode = MessageAckMode.ClientAck
                },
                                          queue, null, HandleMessageEvent, HandleFlowEvent);
                Flow.Start();

                // block the current thread until a confirmation received
                CountdownEvent.Wait();
            }
        }
        /// <summary>
        /// Main entry point to the sample
        /// </summary>
        /// <param name="args"></param>
        public override void SampleCall(string[] args)
        {
            // Parse command line arguments
            ArgParser cmdLineParser = new ArgParser();

            if (!cmdLineParser.Parse(args) || !SampleParseArgs(cmdLineParser))
            {
                // Parse failed.
                PrintUsage(INVALID_ARGUMENTS_ERROR);
                return;
            }

            // Create the API components: starting with the properties
            ContextProperties contextProps = new ContextProperties();
            SessionProperties sessionProps = new SessionProperties();

            sessionProps.Host     = cmdLineParser.Config.IpPort.ip;
            sessionProps.UserName = cmdLineParser.Config.RouterUserVpn.user;
            sessionProps.Password = cmdLineParser.Config.UserPassword;
            sessionProps.SSLValidateCertificate = false;
            sessionProps.ReconnectRetries       = 3;
            if (cmdLineParser.Config.RouterUserVpn.vpn != null)
            {
                sessionProps.VPNName = cmdLineParser.Config.RouterUserVpn.vpn;
            }
            if (cmdLineParser.Config.Compression)
            {
                /* Compression is set as a number from 0-9, where 0 means "disable
                 * compression", and 9 means max compression. The default is no
                 * compression.
                 * Selecting a non-zero compression level auto-selects the
                 * compressed SMF port on the appliance, as long as no SMF port is
                 * explicitly specified. */
                sessionProps.CompressionLevel = 9;
            }

            // Create and connect the API components: create the context and session objects
            IContext context = null;

            session = null;
            IFlow     flow = null;
            IEndpoint provisionedEndpoint = null;

            try
            {
                // Creating the context
                InitContext(cmdLineParser.LogLevel);
                Console.WriteLine("Creating the context ...");
                context = ContextFactory.Instance.CreateContext(contextProps, null);

                // Creating the session
                Console.WriteLine("Creating the session ...");
                session = context.CreateSession(sessionProps, HandleRequestMessage, SampleUtils.HandleSessionEvent);

                // Connecting the session
                Console.WriteLine("Connecting the session ...");
                if (session.Connect() == ReturnCode.SOLCLIENT_OK)
                {
                    Console.WriteLine("Session successfully connected");
                }

                // Provisioning the endpoint

                if (serviceTopic != null)
                {
                    // Provision a Durable Topic Endpoint
                    provisionedEndpoint = ContextFactory.Instance.CreateDurableTopicEndpointEx("cscsmp_sample_" + DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond);
                }
                else
                {
                    provisionedEndpoint = serviceQueue;
                }
                session.Provision(provisionedEndpoint, new EndpointProperties(), ProvisionFlag.WaitForConfirm, null);
                Console.WriteLine(string.Format("Provisioned new endpoint '{0}'", provisionedEndpoint));

                // Create and start flow to to the newly provisioned endpoint
                FlowProperties flowProperties = new FlowProperties();
                flowProperties.AckMode = MessageAckMode.AutoAck;
                flow = session.CreateFlow(flowProperties,
                                          provisionedEndpoint,  /* the newly created endpoint*/
                                          serviceTopic,         /* null if we're listening on a queue*/
                                          HandleRequestMessage, /* local delegate to process request messages and send corresponding reply messages */
                                          SampleUtils.HandleFlowEvent);
                flow.Start();
                Console.WriteLine("Listening for request messages ... Press any key(except for Ctrl+C) to exit");
                Console.In.Read();
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                Cleanup(flow, provisionedEndpoint, session, context);
            }
        }
Пример #7
0
        /// <summary>
        /// Main entry point to the sample
        /// </summary>
        /// <param name="args"></param>
        public override void SampleCall(string[] args)
        {
            // Parse command line arguments
            ArgParser cmdLineParser = new ArgParser();

            if (!cmdLineParser.Parse(args) || !SampleParseArgs(cmdLineParser))
            {
                // Parse failed.
                PrintUsage(INVALID_ARGUMENTS_ERROR);
                return;
            }

            // Create the API components: starting with the properties
            ContextProperties contextProps = new ContextProperties();
            SessionProperties sessionProps = new SessionProperties();

            sessionProps.Host     = cmdLineParser.Config.IpPort.ip;
            sessionProps.UserName = cmdLineParser.Config.RouterUserVpn.user;
            sessionProps.Password = cmdLineParser.Config.UserPassword;
            sessionProps.SSLValidateCertificate = false;
            sessionProps.ReconnectRetries       = 3;
            if (cmdLineParser.Config.RouterUserVpn.vpn != null)
            {
                sessionProps.VPNName = cmdLineParser.Config.RouterUserVpn.vpn;
            }
            if (cmdLineParser.Config.Compression)
            {
                /* Compression is set as a number from 0-9, where 0 means "disable
                 * compression", and 9 means max compression. The default is no
                 * compression.
                 * Selecting a non-zero compression level auto-selects the
                 * compressed SMF port on the appliance, as long as no SMF port is
                 * explicitly specified. */
                sessionProps.CompressionLevel = 9;
            }

            // Create and connect the API components: create the context, session and flow objects
            IContext context = null;

            try
            {
                // Creating the context
                InitContext(cmdLineParser.LogLevel);
                Console.WriteLine("Creating the context ...");
                context = ContextFactory.Instance.CreateContext(contextProps, null);

                // Creating the session
                Console.WriteLine("Creating the session ...");
                session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent);

                // Connecting the session
                Console.WriteLine("Connecting the session ...");
                if (session.Connect() == ReturnCode.SOLCLIENT_OK)
                {
                    Console.WriteLine("Session successfully connected");
                }
                // Creating the temporary queue and corresponding flow
                IQueue         replyToQueue   = session.CreateTemporaryQueue();
                FlowProperties flowProperties = new FlowProperties();
                flow = session.CreateFlow(flowProperties,
                                          replyToQueue,
                                          null,               /* null when binding to a queue*/
                                          HandleReplyMessage, /* defined in this sample to handle receipt of reply message*/
                                          SampleUtils.HandleFlowEvent);
                flow.Start();

                doRequest(requestDestination, replyToQueue, Operation.PLUS, 5, 4);
                Thread.Sleep(1000);
                doRequest(requestDestination, replyToQueue, Operation.MINUS, 5, 4);
                Thread.Sleep(1000);
                doRequest(requestDestination, replyToQueue, Operation.TIMES, 5, 4);
                Thread.Sleep(1000);
                doRequest(requestDestination, replyToQueue, Operation.DIVIDE, 5, 4);
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                if (flow != null)
                {
                    flow.Dispose();
                }
                if (session != null)
                {
                    session.Dispose();
                }
                if (context != null)
                {
                    context.Dispose();
                }
                // Must cleanup after.
                CleanupContext();
            }
        }
        public override void SampleCall(string[] args)
        {
            // Parse arguments and initialize Session properties.
            ArgParser cmdLineParser = new ArgParser();

            if (!cmdLineParser.Parse(args))
            {
                // Parse failed.
                PrintUsage(INVALID_ARGUMENTS_ERROR);
                return;
            }
            // Create Session properties from the command line options.
            SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config);

            try
            {
                InitContext(cmdLineParser.LogLevel);

                // Create and connect 'sessionA' with No Local delivery set to false.
                sessionProps.NoLocal = false; // No Local is set to 'false' by default.
                InitializeAndAssertCapabilities(ref context, ref sessionA, "sessionA", sessionProps);

                // Create and connect 'sessionB' with No Local delivery set to true.
                sessionProps.NoLocal = true; // <-- this is how we set NoLocal at the session level
                InitializeAndAssertCapabilities(ref context, ref sessionB, "sessionB", sessionProps);

                // Create a Flow to a temporary Queue within sessionA.
                IQueue         queue     = sessionB.CreateTemporaryQueue();
                FlowProperties flowProps = new FlowProperties();
                flowProps.NoLocal      = true; // <-- this is how we set NoLocal at the flow level
                flowProps.BindBlocking = true;
                flowA = sessionA.CreateFlow(flowProps, queue, null, HandleMessageEvent, SampleUtils.HandleFlowEvent);
                flowA.Start();

                // Add a Topic subscription to sessionB.
                ITopic topic = ContextFactory.Instance.CreateTopic(SampleUtils.SAMPLE_TOPIC);
                sessionB.Subscribe(topic, true /*wait for confirm*/);

                // Publish a Direct message to Topic T from each Session; verify it is not delivered locally.
                IMessage msg = ContextFactory.Instance.CreateMessage();
                msg.BinaryAttachment = Encoding.ASCII.GetBytes(SampleUtils.MSG_ATTACHMENTTEXT);
                msg.Destination      = topic;
                msg.DeliveryMode     = MessageDeliveryMode.Direct;
                // Send from 'sessionA'.
                Console.WriteLine(string.Format("\nSending a direct message to topic '{0}' from sessionA", topic.ToString()));
                sessionA.Send(msg);
                Thread.Sleep(500);
                PrintCounters();
                Console.WriteLine(string.Format("Expecting msgCounterForSessionB to be 1, it's '{0}'", msgCounterForSessionB));
                Console.WriteLine(string.Format("Expecting msgCounterForSessionA to be 0, it's '{0}'", msgCounterForSessionA));
                ResetCounters();
                // Send from 'sessionB'.
                Console.WriteLine(string.Format("\nSending a direct message to topic '{0}' from sessionB", topic.ToString()));
                sessionB.Send(msg);
                Thread.Sleep(500);
                PrintCounters();
                Console.WriteLine(string.Format("Expecting msgCounterForSessionA to be 0, it's '{0}'", msgCounterForSessionA));
                Console.WriteLine(string.Format("Expecting msgCounterForSessionB to be 0, it's '{0}'", msgCounterForSessionB));
                ResetCounters();


                // Publish a message to the Queue on each Session; verify it is not delivered locally.
                msg.Destination  = queue;
                msg.DeliveryMode = MessageDeliveryMode.Persistent;
                // Send from 'sessionA'.
                Console.WriteLine(string.Format("\nSending a persistent message to queue '{0}' from sessionA", queue.ToString()));
                sessionA.Send(msg);
                Thread.Sleep(500);
                PrintCounters();
                Console.WriteLine(string.Format("Expecting msgCounterForFlowA to be 0, it's '{0}'", msgCounterForFlowA));
                ResetCounters();
                // Send from 'sessionB'.
                Console.WriteLine(string.Format("\nSending a persistent message to queue '{0}' from sessionB", queue.ToString()));
                sessionB.Send(msg);
                Thread.Sleep(500);
                PrintCounters();
                Console.WriteLine(string.Format("Expecting msgCounterForFlowA to be 1, it's '{0}'", msgCounterForFlowA));
                ResetCounters();
                Console.WriteLine("\nDone");
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                if (flowA != null)
                {
                    flowA.Dispose();
                }
                if (sessionA != null)
                {
                    sessionA.Dispose();
                }
                if (context != null)
                {
                    context.Dispose();
                }
                // Must cleanup after.
                CleanupContext();
            }
        }