// // 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 //====================================================================================================== // Code originally contributed by Microsoft Corporation. // This contribution to the Stonehenge project is limited strictly // to the source code that is submitted in this submission. // Any technology, including underlying platform technology, // that is referenced or required by the submitted source code // is not a part of the contribution. // For example and not by way of limitation, // any systems/Windows libraries (WPF, WCF, ASP.NET etc.) // required to run the submitted source code is not a part of the contribution //====================================================================================================== //====================================================================================================== // Contains .NET StockTrader application specific utility methods and constants/statics used by the app. //====================================================================================================== using System; using System.Collections.Generic; using System.Diagnostics; using System.ServiceModel; using System.ServiceModel.Description; using System.Configuration; using Trade.Utility.Loggers; namespace Trade.Utility { /// /// Utility class with constants used in StockTrader app/services. /// public static class StockTraderUtility { //Exception Messages and Strings public static readonly string EXCEPTION_DOTNET_DUPLICATE_PRIMARY_KEY = "Violation of PRIMARY KEY"; public static readonly string EXCEPTION_WEBSPHERE_DUPLICATE_PRIMARY_KEY = "org.omg.CORBA.portable.UnknownException"; public static readonly string EXCEPTION_MESSAGE_INVALID_ORDERMODE_CONFIG = "This 'OrderMode' setting is not a valid setting (settings are case-sensitive)."; public static readonly string EXCEPTION_MESSAGE_INVALID_TXMMODEL_CONFIG = "This 'Use System.Transactions Globally' setting is not a valid setting. Valid settings are 'true' or 'false'. Please fix in: "; public static readonly string EXCEPTION_MESSAGE_VALID_ORDERMODEVALUES = "Valid values are: 'ASync_DotNet_Http', 'ASync_DotNet_WsHttp_MSecurity', 'ASync_PHP_Http', 'ASync_PHP_WsHttp_MSecurity', 'ASync_WSAS_Http', 'ASync_WSAS_WsHttp_MSecurity'."; public static readonly string EXCEPTION_MESSAGE_INVALID_HOLDING_BAD_QUOTE = "Holding with non-valid Quote Symbol: holdingID="; public static readonly string EXCEPTION_MESSAGE_INVALID_HOLDING_NOT_FOUND = "Holding not found!"; public static readonly string EXCEPTION_MESSAGE_INVALID_HOLDING_ZERO_BASIS = "Holding with zero basis!: holdingID="; public static readonly string EXCEPTION_MESSAGE_NULL_DATE = "Data is Null. This method or property cannot be called on Null values."; public static readonly string EXCEPTION_MESSAGE_BAD_ORDER_PARMS = "Your order was not placed becuase the requested quantity was not valid."; public static readonly string EXCEPTION_MESSAGE_BAD_ACTION = "Your order was not placed becuase the requested action is invalid."; public static readonly string EXCEPTION_MESSAGE_BAD_ORDER_RETURN = "We are sorry but your order could not be placed. Please try again later."; public static readonly string EXCEPTION_MESSAGE_ACID_REGISTRATION = "ACID TEST ON INSERT USERID 'ACID': PLANNED EXCEPTION THROWN!"; public static readonly string EXCEPTION_MESSAGE_ACID_BUY = "PLANNED ACID TEST: SYMBOL 'ACIDBUY' PLANNED EXCEPTION THROWN!"; public static readonly string EXCEPTION_MESSAGE_ACID_SELL = "PLANNED ACID TEST: SYMBOL 'ACIDSELL' PLANNED EXCEPTION THROWN!"; public static readonly string EXCEPTION_MESSAGE_BADORDERTYPE = "Sorry, this order type is not allowed."; public static readonly string EXCEPTION_MESSAGE_INVALID_ORDERFORWARDBEHAVIOR_CONFIG = "This 'Order Processing Behavior' setting is not a valid setting (settings are case-sensitive). Please fix in: "; public static readonly string EXCEPTION_MESSAGE_INVALID_ORDERFORWARDMODE_CONFIG = "This 'OrderForwardMode' setting is not a valid setting (settings are case-sensitive). Please fix in: "; public static readonly string EXCEPTION_MESSAGE_VALID_ORDERFORWARDMODEVALUES = "Valid values are: 'ASync_DotNet_Http', 'ASync_DotNet_WsHttp_MSecurity', 'ASync_PHP_Http', 'ASync_PHP_WsHttp_MSecurity', 'ASync_WSAS_Http', 'ASync_WSAS_WsHttp_MSecurity'."; public static readonly string EXCEPTION_MESSAGE_VALID_ORDERFORWARDBEHAVIORVALUES = "Valid values are: 'Forward' and 'Standard'."; public static readonly string EXCEPTION_WEBSPHERE_USERID_NOTFOUND = "javax.ejb.ObjectNotFoundException"; public static readonly string EXCEPTION_WEBSPHERE_INVALID_PASSWORD = "Incorrect password"; public static readonly string EXCEPTION_MESSAGE_INVALID_ACCESSMODE_CONFIG = "This 'AccessMode' setting is not a valid setting (settings are case-sensitive)."; public static readonly string EXCEPTION_MESSAGE_VALID_ACCESSMODEVALUES = "Valid values are: 'DotNet_Http_WcfService' (for SOA activation via WCF Self-Host/Http), 'DotNet_WsHttp_WcfService' (for SOA activation via WCF Self-Host/WsHttp), 'PHP_Http_WebService' (for SOA activation via WCF against PHP (WSF) services) and 'WSAS_Http_WebService' (for SOA activation via WCF against WSAS services)."; public static readonly string EXCEPTION_MESSAGE_DUPLICATE_PRIMARY_KEY = "User ID Already Exists! Please Try a Different User ID."; public static readonly string EXCEPTION_MESSAGE_INVALID_LOGIN = "Error Logging In. Invalid Username or Password!"; public static readonly string EXCEPTION_MESSAGE_BAD_CONFIG = "Error Loading Configuration from Configuration Service. Please confirm that the {0} client is in the configuration database."; //Define max lengths for input fields; public static readonly int ADDRESS_MAX_LENGTH = 100; public static readonly int EMAIL_MAX_LENGTH = 100; public static readonly int CREDITCARD_MAX_LENGTH = 100; public static readonly int FULLNAME_MAX_LENGTH = 100; public static readonly int USERID_MAX_LENGTH = 50; public static readonly int PASSWORD_MAX_LENGTH = 100; public static readonly int OPENBALANCE_MAX_LENGTH = 20; public static readonly int QUOTESYMBOL_MAX_LENGTH = 15; public static readonly int SYMBOLSTRING_MAXLENGTH = 30; //Trade Business Logic constants public static readonly decimal BUY_FEE = 15.95m; public static readonly decimal SELL_FEE = 25.95m; public static readonly decimal PENNY_STOCK_P = .1m; public static readonly decimal STOCK_P_HIGH_BAR = 1000m; public static readonly decimal STOCK_P_HIGH_BAR_CRASH = .05m; public static readonly decimal JUNK_STOCK_MIRACLE_MULTIPLIER = 500m; public static readonly int STOCK_CHANGE_MAX_PERCENT = 5; //map user strings to ints for faster lookups. We want to catch invalid settings //so the user knows what tx model they are running within a service. public const string TRANSACTION_STRING_SYSTEMDOTTRANSACTION_TRANSACTION = "true"; public const string TRANSACTION_STRING_ADONET_TRANSACTION = "false"; public const int TRANSACTION_MODEL_SYSTEMDOTTRANSACTION_TRANSACTION = 1; public const int TRANSACTION_MODEL_ADONET_TRANSACTION = 0; //ACID Test Codes public static readonly string ACID_TEST_USER = "ACIDUSER"; public static readonly string ACID_TEST_BUY = "ACIDBUY"; public static readonly string ACID_TEST_SELL = "ACIDSELL"; public const string REGISTER_USER = "Register"; //Service Host Names. These are good candidates to move into the various repositories to make them more dynamic //than defined in code as constants. Perhaps for next release of StockTrader--easy to do. public const string ORDER_PROCESSOR_SERVICE = "StockTrader Order Processor Service"; public const string WEBAPPLICATION = ".NET StockTrader Web Application"; public const string BUSINESS_SERVICES = "StockTrader Business Services"; //Endpoint - Connected Service Names -- the various modes/bindings we can connect from Web app to Business Services //First for Business Services public const string DOTNET_SELFHOST_BSL_HTTP = ".NET StockTrader Business Services Http/SOAP"; public const string DOTNETSELFHOST_BSL_WSHTTP = ".NET StockTrader Business Services Http/WS-* (M-Security)"; public const string WSO2_BSL_WSHTTP = "WSO2 StockTrader Business Services Http/WS-* (M-Security)"; //Now Endpoint - Connected Service Names for Order Processor public const string DOTNET_SELFHOST_OPS_HTTP = ".NET Order Processor Async-Http (SOAP)"; public const string DOTNET_SELFHOST_OPS_WSHTTP = ".NET Order Processor Async-Http WS-* (M-Security)"; public const string WSO2_OPS_WSHTTP = "WSO2 Order Processor Async-Http WS-* (M-Security)"; //Order Codes public const string ORDER_TYPE_BUY = "buy"; public const string ORDER_TYPE_SELL = "sell"; public const string ORDER_TYPE_SELL_ENHANCED = "sellEnhanced"; public static readonly string ORDER_STATUS_OPEN = "open"; public static readonly string ORDER_STATUS_CLOSED = "closed"; public static readonly string ORDER_STATUS_COMPLETED = "completed"; public const string DAL_SQLSERVER = "Trade.DALSQLServer"; public const string DAL_MYSQL = "Trade.DALMySQL"; public const string DAL_ORACLE = "Trade.DALOracle"; public const string DAL_DB2 = "Trade.DALDB2"; //Used to cache a Random class used for calculating random price changes vs. creating new //Random class on each buy/sell; private static Random rand = new Random(DateTime.Now.Millisecond); private static ILogger logger; public static ILogger Logger { get { if (logger == null) { string logging_enabled = ConfigurationManager.AppSettings.Get("LOGGING_ENABLED"); if (!logging_enabled.Equals("ON", StringComparison.InvariantCultureIgnoreCase)) { logger = new NullLogger(); } else { string loggerMode = ConfigurationManager.AppSettings.Get("LOGGER_MODE"); switch (loggerMode) { case ("CONSOLE"): logger = new ConsoleLogger(); break; case ("EVENT_VIEWER"): logger = new EventViewerLogger(); break; default: logger = new NullLogger(); break; } } } return logger; } } //Dermines how much a stock price will change after a trade. public static decimal getRandomPriceChangeFactor(decimal current_price) { if (current_price <= PENNY_STOCK_P) return JUNK_STOCK_MIRACLE_MULTIPLIER; else if (current_price >= STOCK_P_HIGH_BAR) return STOCK_P_HIGH_BAR_CRASH; decimal factor = 0m; int y = rand.Next(1, STOCK_CHANGE_MAX_PERCENT); int x = rand.Next(); if (x % 2 == 0) { factor = 1 - ((decimal)y) / 100m; } else factor = 1 + ((decimal)y) / 100m; return factor; } //How much the brokerage is going to charge! public static decimal getOrderFee(string orderType) { if (orderType.ToLower().Equals(ORDER_TYPE_BUY) || orderType.ToLower().Equals(ORDER_TYPE_SELL)) return BUY_FEE; else return SELL_FEE; } public static void DescribeService(ServiceHost host) { //iterate and display all endpoints via host.Description.Endpoints Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Configuration for {0} \n", Console.Title); ServiceDescription svcDesc = host.Description; Console.WriteLine("Configuration name: {0}", svcDesc.ConfigurationName); // Iterate through the endpoints contained in the ServiceDescription foreach (ServiceEndpoint se in svcDesc.Endpoints) { Console.WriteLine("Endpoint:"); Console.WriteLine("\tName: {0}", se.Name); Console.WriteLine("\tAddress: {0}", se.Address.ToString()); Console.WriteLine("\tBinding: {0}", se.Binding.ToString()); Console.WriteLine("\tContract: {0}", se.Contract.ConfigurationName); KeyedByTypeCollection behaviors = se.Behaviors; foreach (IEndpointBehavior behavior in behaviors) { Console.WriteLine("Behavior: {0}", behavior.ToString()); } } Console.WriteLine(); Console.WriteLine("Service Description name: {0}", svcDesc.Name); Console.WriteLine("Service Description namespace: {0}", svcDesc.Namespace); Console.WriteLine("Service Type: {0}", svcDesc.ServiceType); Console.WriteLine(); Console.WriteLine(); } } }