Esempio n. 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;
            }
        }
        /// <summary>
        /// Main function in the sample.
        /// </summary>
        /// <param name="args"></param>
        public override void SampleCall(string[] args)
        {
            #region Parse Arguments
            ArgParser cmdLineParser = new ArgParser();
            if (!cmdLineParser.Parse(args))
            {
                // parse failed
                PrintUsage(INVALID_ARGUMENTS_ERROR);
                return;
            }
            if (!SampleParseArgs(cmdLineParser))
            {
                // parse failed for sample's arguments
                PrintUsage(INVALID_ARGUMENTS_ERROR);
                return;
            }
            #endregion

            #region Initialize properties from command line
            // Initialize the properties.
            ContextProperties contextProps = new ContextProperties();
            SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config);
            #endregion

            // Define IContext and ISession.
            IContext       context       = null;
            ISession       session       = null;
            ITopicEndpoint topicEndpoint = null;
            try
            {
                InitContext(cmdLineParser.LogLevel);
                Console.WriteLine("About to create the Context ...");
                context = ContextFactory.Instance.CreateContext(contextProps, null);
                Console.WriteLine("Context successfully created. ");

                Console.WriteLine("About to create the Session ...");
                session = context.CreateSession(sessionProps,
                                                SampleUtils.HandleMessageEvent,
                                                SampleUtils.HandleSessionEvent);
                Console.WriteLine("Session successfully created.");

                Console.WriteLine("About to connect the Session ...");
                if (session.Connect() == ReturnCode.SOLCLIENT_OK)
                {
                    Console.WriteLine("Session successfully connected");
                    Console.WriteLine(GetRouterInfo(session));
                }
                if (!session.IsCapable(CapabilityType.SUB_FLOW_GUARANTEED) || !(session.IsCapable(CapabilityType.TEMP_ENDPOINT)))
                {
                    Console.WriteLine(string.Format("Capabilities '{0}' and '{1}' are required to run this sample",
                                                    CapabilityType.SUB_FLOW_GUARANTEED,
                                                    CapabilityType.TEMP_ENDPOINT));
                    return;
                }
                ITopic topic = null;
                if (cmdLineParser.Config.UseDurableEndpoint)
                {
                    Console.WriteLine(string.Format("A durable topic endpoint with name '{0}' must be provisioned and accessible on the appliance in the same user's Message VPN.)", SampleUtils.SAMPLE_TOPICENDPOINT));
                    topicEndpoint = ContextFactory.Instance.CreateDurableTopicEndpointEx(SampleUtils.SAMPLE_TOPICENDPOINT);
                    topic         = ContextFactory.Instance.CreateTopic(SampleUtils.SAMPLE_TOPIC);
                }
                else
                {
                    Console.WriteLine("Creating a temporary Topic");
                    topic         = session.CreateTemporaryTopic();
                    topicEndpoint = session.CreateNonDurableTopicEndpoint();
                }
                FlowProperties flowProps = new FlowProperties();
                // The Flow is created in a started state, so it is ready to receive messages.
                flowProps.FlowStartState = true;
                // AutoAck means that the received messages on the Flow
                // will be implicitly acked on return from the message event handler
                // specified in CreateFlow().
                flowProps.AckMode = MessageAckMode.AutoAck;
                // NON-BLOCKING FLOW CREATE: make sure that the flowProps.BindBlocking is set to false;
                flowProps.BindBlocking = false;

                // NON-BLOCKING FLOW CREATE: to demonstrate waiting on flow up event
                EventWaitHandle waitForFlowUpEvent = new AutoResetEvent(false);

                flow = session.CreateFlow(flowProps, topicEndpoint, topic,
                                          SampleUtils.HandleMessageEvent,
                                          new EventHandler <FlowEventArgs>(
                                              delegate(object source, FlowEventArgs evt)
                {
                    if (evt.Event == FlowEvent.UpNotice)
                    {
                        waitForFlowUpEvent.Set();
                    }
                }));

                if (waitForFlowUpEvent.WaitOne(5000, false))
                {
                    // We got a FlowEvent.UpNotice.
                    Console.Out.WriteLine("Flow created, we can proceed now");
                }
                else
                {
                    // We did not get a FlowEvent.UpNotice within five seconds.
                    Console.Out.WriteLine("Did not get a FlowEvent.UpNotice within 5 secs, exiting ...");
                    return;
                }
                // Send a number of messages to the Topic.
                IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session);
                message.Destination = topic;
                Console.WriteLine(string.Format("About to send {0} messages ...", cmdLineParser.Config.NumberOfMessagesToPublish));
                for (int i = 0; i < cmdLineParser.Config.NumberOfMessagesToPublish; i++)
                {
                    if (session.Send(message) == ReturnCode.SOLCLIENT_OK)
                    {
                        Console.Write(".");
                    }
                    Thread.Sleep(1000); // wait for 1.0 seconds.
                }
                Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000));
                Thread.Sleep(Timeout);
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                bool flowWasConnected = (flow != null);
                if (flow != null)
                {
                    flow.Dispose();
                }
                // Durable Topic Endpoints will continue getting messages on the registered Topic
                // subscription if client applications do not unsubscribe.
                // Non-durable Topic Endpoints will be cleaned up automatically after client applications
                // dispose the Flows bound to them.
                //
                // The following code block demonstrates how to unsubscribe or remove a subscribed Topic on
                // the durable Topic Endpoint.
                // Two conditions must be met:
                // - The durable Topic Endpoint must have at least 'Modify Topic' permission enabled.
                // - No flows are currently bound to the durable Topic Endpoint in question.
                if (topicEndpoint != null && topicEndpoint.Durable && session != null && flowWasConnected)
                {
                    Console.WriteLine(string.Format("About to unsubscribe from durable Topic Endpoint '{0}'", ((ITopicEndpoint)topicEndpoint).Name));
                    session.Unsubscribe(topicEndpoint, "Unsubscribe Operation Correlation ID");
                }
                if (session != null)
                {
                    session.Dispose();
                }
                if (context != null)
                {
                    context.Dispose();
                }
                // Must cleanup after.
                CleanupContext();
            }
        }