//
// 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();
}
}
}