// // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // .Net StockTrader Sample WCF Application for Benchmarking, Performance Analysis and Design Considerations for Service-Oriented Applications //====================================================================================================== // The Order Processor Service implementation class/business logic. //====================================================================================================== using System; using System.Configuration; using System.Diagnostics; using System.Messaging; using System.Transactions; using System.ServiceModel; using System.ServiceModel.Channels; using System.Runtime.Serialization; //using ConfigService.ServiceConfigurationBase; //using ConfigService.ServiceConfigurationUtility; //using ConfigService.ServiceConfigurationHelper; using Trade.BusinessServiceDataContract; using Trade.OrderProcessorContract; using Trade.OrderProcessorServiceConfigurationSettings; using Trade.Utility; //using Trade.OrderProcessorAsyncClient; namespace Trade.OrderProcessorImplementation { /// /// Service class which implements the Order Processor service contract. /// ReleaseServiceInstanceOnTransactionComplete is marked as false to support transacted batches from the /// transacted (persisted) durable MSMQ message queue. This is required! /// [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)] public class OrderProcessor : IOrderProcessor { public OrderProcessor() { } /// /// Interesting in that this service contract is a one-way contract. However, it // turns out this online check works fine in that we are loosely couple when working with MSMQ // and still tightly coupled on one-way TCP or HTTP bindings. The behavior is such // that this method will fail from calling client only on TCP/HTTP one-way (Async) // bindings, which happens regardless on any method call; but will not fail on MSMQ bindings // if the messaging service is running. If MSMQ messaging service is not running at the endpoint, // we will have endpoint not found detection as desired. /// public void isOnline() { return; } /// /// SubmitOrder service operation is a service operation that processes order messages from the client /// coming in via TCP, HTTP, or a non-transacted (volatile) MSMQ WCF binding from either the BSL or another remote instance /// of the Order Processor Service running in 'Forward' mode. /// This method *always* uses a System.Transaction tx to ensure database integrity. /// However, since it is receiving from a non-persisted format, the order could possibly be lost /// even as database integrity is maintained on the processing of the order itself. /// This is because if a received order is not processed successfully to the database, the message /// will not be automatically preserved by the source it is being received from since that source /// is not a durable (persisted) source. /// /// Order to submit. public void SubmitOrder(OrderDataModel order) { System.Transactions.TransactionOptions txOps = new TransactionOptions(); txOps.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; txOps.Timeout = TimeSpan.FromSeconds(Settings.SYSTEMDOTTRANSACTION_TIMEOUT); //Start our System.Transactions tx with the options set above. using (TransactionScope tx = new TransactionScope(TransactionScopeOption.Required, txOps)) { try { processOrder(order); //Complete transaction scope! tx.Complete(); } catch { throw; } } return; } /// /// Processes the order and creates holding, or sells stock. /// /// Order to process. private void processOrder(OrderDataModel queuedOrder) { //You could extend this application by transforming the order message //as it comes in to another format, if required. In this case, //no transformation actually takes place since the types are the same. //You can imagine different systems bridged might have different schema, //however, and transformations could be rather easily accomplished here. if (queuedOrder.orderID % Settings.DISPLAYNUMBERORDERITERATIONS == 0) { string message = string.Format("Processing Order {0}, symbol {1}, type {2}.", queuedOrder.orderID.ToString(), queuedOrder.symbol, queuedOrder.orderType); StockTraderUtility.Logger.WriteDebugMessage(message + "\n"); } ProcessOrder orderService = new ProcessOrder(); orderService.ProcessAndCompleteOrder(queuedOrder); return; } } }