Пример #1
0
 protected virtual void Dispose(bool disposing)
 {
     if (!disposedValue)
     {
         if (disposing)
         {
             if (Session != null)
             {
                 Session.Dispose();
                 Session = null;
             }
             if (Queue != null)
             {
                 Queue.Dispose();
                 Queue = null;
             }
             if (Flow != null)
             {
                 Flow.Dispose();
                 Flow = null;
             }
         }
         disposedValue = true;
     }
 }
        /// <summary>
        /// Dump messages received from a given Queue.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="queue"></param>
        /// <param name="waitTimeout"></param>
        /// <param name="autoack">If true, messages will be automaticaly acked</param>
        private void DumpMessagesReceivedFromQueue(ISession session, IQueue queue, int waitTimeout, bool autoack)
        {
            FlowProperties flowProps = new FlowProperties();

            if (autoack)
            {
                flowProps.AckMode = MessageAckMode.AutoAck;
            }
            else
            {
                flowProps.AckMode = MessageAckMode.ClientAck;
            }
            // Clear messages on the shared message list '_deliveredMessages' first.
            lock (_deliveredMessages)
            {
                _deliveredMessages.Clear();
            }
            IFlow flow = session.CreateFlow(flowProps, queue, null, HandleMessageEvent, SampleUtils.HandleFlowEvent);

            // To keep the sample simple, it is good enough to use Thread.Sleep().
            Thread.Sleep(waitTimeout);
            // Then dispose.
            flow.Dispose();
            // Dump the received messages.
            Console.WriteLine(string.Format("\n@@@ Received {0} message(s) over queue {1}", _deliveredMessages.Count, queue.ToString()));
            foreach (IMessage deliveredMsg in _deliveredMessages)
            {
                Console.WriteLine(deliveredMsg.Dump() + "\n");
            }
        }
Пример #3
0
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    Flow.Dispose();
                }
                disposedValue = true;
            }
        }
 /// <summary>
 ///
 /// </summary>
 private void Cleanup(IFlow flow, IEndpoint provisionedEndpoint, ISession session, IContext context)
 {
     if (flow != null)
     {
         flow.Dispose();
     }
     if (provisionedEndpoint != null)
     {
         session.Deprovision(provisionedEndpoint, ProvisionFlag.WaitForConfirm, null);
     }
     if (session != null)
     {
         session.Dispose();
     }
     if (context != null)
     {
         context.Dispose();
     }
     // Must cleanup after.
     CleanupContext();
 }
        /// <summary>
        /// The 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;
            }
            cmdLineParser.Config.DeliveryMode = MessageDeliveryMode.Persistent;
            cmdLineParser.Config.DestMode     = DestMode.QUEUE;
            #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;
            IFlow    flow    = 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.SELECTOR))
                {
                    Console.WriteLine(string.Format("Capability '{0}' is required to run this sample",
                                                    CapabilityType.SELECTOR));
                    return;
                }
                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;
                }

                // The creation of the Queue object. Temporary destinations must be
                // acquired from a connected session, as they require knowledge
                // about the connected appliance.
                IQueue queue = session.CreateTemporaryQueue();

                // The creation of a flow. A FlowReceiver is acquired for consuming
                // messages from a specified endpoint.
                //
                // The selector "pasta = 'rotini' OR pasta = 'farfalle'" is used to
                // select only messages matching those pasta types in their user
                // property map.
                FlowProperties flowProps = new FlowProperties();
                flowProps.FlowStartState = true;  // created in a started state;
                flowProps.Selector       = "pasta = 'rotini' OR pasta = 'farfalle'";
                flow = session.CreateFlow(flowProps, queue, null, SampleUtils.HandleMessageEvent, SampleUtils.HandleFlowEvent);

                // Now publish a number of messages to queue, the user should only get the ones with 'rotini' or 'farfalle'.
                // Note that this uses SDT and custom header properties, which could impact performance.
                IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session);
                message.Destination = queue;
                string[] pastas = new string[] { "macaroni", "fettuccini", "farfalle", "fiori", "rotini", "penne" };
                for (int i = 0; i < pastas.Length; i++)
                {
                    IMapContainer userProps = message.CreateUserPropertyMap();
                    userProps.AddString("pasta", pastas[i]);
                    if (session.Send(message) == ReturnCode.SOLCLIENT_OK)
                    {
                        Console.WriteLine(String.Format("- Sent {0}", pastas[i]));
                    }
                }
                Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting. Expecting 2 messages to match the selector ", Timeout / 1000));
                Thread.Sleep(Timeout);
            }
            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();
            }
        }
        /// <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();
            }
        }
Пример #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();
            }
        }
        /// <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;
            IQueue   queue   = 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;
                }

                #region Provision an exclusive queue
                EndpointProperties endpointProps = new EndpointProperties();
                // Set permissions to allow all permissions to others.
                endpointProps.Permission = EndpointProperties.EndpointPermission.Delete;
                // Set access type to exclusive.
                endpointProps.AccessType = EndpointProperties.EndpointAccessType.Exclusive;
                // Set quota to 100 MB.
                endpointProps.Quota = 100;
                string queueName = "solclient_dotnet_sample_ActiveFlowIndication_" + (new Random()).Next(1000);

                queue = ContextFactory.Instance.CreateQueue(queueName);
                Console.WriteLine(String.Format("About to provision queue '{0}' on the appliance", queueName));
                try
                {
                    session.Provision(queue /* endpoint */,
                                      endpointProps /*endpoint properties */,
                                      ProvisionFlag.WaitForConfirm /* block waiting for confirmation */,
                                      null /*no correlation key*/);
                    Console.WriteLine("Endpoint queue successfully provisioned on the appliance");
                }
                catch (Exception ex)
                {
                    PrintException(ex);
                    Console.WriteLine("Exiting");
                    return;
                }
                #endregion

                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;
                //Activate the active flow indication events
                flowProps.ActiveFlowInd = true;

                EventWaitHandle waitForFlowActiveEvent = new AutoResetEvent(false);

                flow1 = session.CreateFlow(flowProps, queue, null,
                                           SampleUtils.HandleMessageEvent,
                                           new EventHandler <FlowEventArgs>(
                                               delegate(object source, FlowEventArgs evt)
                {
                    switch (evt.Event)
                    {
                    case FlowEvent.FlowActive:
                        Console.Out.WriteLine("Flow 1 Active event received");
                        waitForFlowActiveEvent.Set();
                        break;
                    }
                }));

                if (waitForFlowActiveEvent.WaitOne(5000, false))
                {
                    waitForFlowActiveEvent.Reset();
                }
                else
                {
                    // We did not get a FlowEvent.UpNotice within five seconds.
                    Console.Out.WriteLine("Did not get a FlowEvent.FlowActive for flow 1 within 5 secs, exiting ...");
                    return;
                }

                flow2 = session.CreateFlow(flowProps, queue, null,
                                           SampleUtils.HandleMessageEvent,
                                           new EventHandler <FlowEventArgs>(
                                               delegate(object source, FlowEventArgs evt)
                {
                    switch (evt.Event)
                    {
                    case FlowEvent.FlowInactive:
                        Console.Out.WriteLine("Flow 2 Inactive event received");
                        break;

                    case FlowEvent.FlowActive:
                        Console.Out.WriteLine("Flow 2 Active event received");
                        waitForFlowActiveEvent.Set();
                        break;
                    }
                }));
                Console.WriteLine("Flow 2 started.");

                Console.WriteLine("Stopping flow 1.");
                if (flow1.Stop() == ReturnCode.SOLCLIENT_OK)
                {
                    Console.WriteLine("Flow 1 stopped.");
                }
                else
                {
                    Console.WriteLine("Failure while stopping flow 1.  Exiting ...");
                    return;
                }
                Console.WriteLine("Disposing of flow 1");
                flow1.Dispose();
                flow1 = null;
                Console.WriteLine("Flow 1 has been disposed");
                if (waitForFlowActiveEvent.WaitOne(5000, false))
                {
                    waitForFlowActiveEvent.Reset();
                }
                else
                {
                    // We did not get a FlowEvent.UpNotice within five seconds.
                    Console.Out.WriteLine("Did not get a FlowEvent.FlowActive for flow 2 within 5 secs, exiting ...");
                    return;
                }

                Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000));
                Thread.Sleep(Timeout);
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                if (flow1 != null)
                {
                    flow1.Dispose();
                }
                if (flow2 != null)
                {
                    flow2.Dispose();
                }
                if (queue != null)
                {
                    if (session != null)
                    {
                        session.Deprovision(queue, ProvisionFlag.WaitForConfirm, null);
                    }
                    queue.Dispose();
                }

                if (session != null)
                {
                    session.Dispose();
                }
                if (context != null)
                {
                    context.Dispose();
                }
                // Must cleanup after.
                CleanupContext();
            }
        }
        /// <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;
            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;
                }
                IQueue queue = null;
                if (cmdLineParser.Config.UseDurableEndpoint)
                {
                    Console.WriteLine(string.Format("A non-temporary queue with name '{0}' must be provisioned and accessible on the appliance within the same user's Message VPN)", SampleUtils.SAMPLE_QUEUE));
                    queue = ContextFactory.Instance.CreateQueue(SampleUtils.SAMPLE_QUEUE);
                }
                else
                {
                    Console.WriteLine("Creating a temporary queue");
                    queue = session.CreateTemporaryQueue();
                }
                FlowProperties flowProps = new FlowProperties();
                // The flow is created in a started state, so it is ready to receive messages.
                flowProps.FlowStartState = true;
                // ClientAck, which means that the received messages on the Flow
                // must be explicitly acked, otherwise they will be redelivered to the client
                // when the Flow reconnects.
                // ClientAck was chosen simply to illustrate ClientAck and that clients
                // can use AutoAck instead.
                flowProps.AckMode = MessageAckMode.ClientAck;

                flow = session.CreateFlow(flowProps, queue, null,
                                          // Demonstrates explicit client acknoweldgment of received messages.
                                          HandleMessageAndAck,
                                          SampleUtils.HandleFlowEvent);
                // Now publish a number of messages to the Queue.
                IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session);
                message.Destination = queue;
                Console.WriteLine(string.Format("About to send {0} message(s) ...", cmdLineParser.Config.NumberOfMessagesToPublish));

                // Send a number of messages to the Queue.
                for (int i = 0; i < cmdLineParser.Config.NumberOfMessagesToPublish; i++)
                {
                    if (session.Send(message) == ReturnCode.SOLCLIENT_OK)
                    {
                        Console.Write(".");
                    }
                    Thread.Sleep(1000); // Wait for 0.5 seconds
                }
                Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000));
                Thread.Sleep(Timeout);
            }
            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();
            }
        }