Initial project's source code check-in.
This commit is contained in:
commit
b03b0b373f
4573 changed files with 981205 additions and 0 deletions
|
@ -0,0 +1,543 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
public class DomainNameController : ServiceProvisioningBase, IServiceProvisioning
|
||||
{
|
||||
public const string SOURCE_NAME = "SPF_DOMAIN_NAME";
|
||||
|
||||
public static Dictionary<int, string> ApiErrorCodesMap;
|
||||
|
||||
static DomainNameController()
|
||||
{
|
||||
ApiErrorCodesMap = new Dictionary<int, string>();
|
||||
ApiErrorCodesMap.Add(BusinessErrorCodes.ERROR_DOMAIN_QUOTA_LIMIT, ERROR_DOMAIN_QUOTA_EXCEEDED);
|
||||
}
|
||||
|
||||
#region Trace Messages
|
||||
|
||||
public const string START_ACTIVATION_MSG = "Starting domain name activation";
|
||||
public const string START_SUSPENSION_MSG = "Starting domain name suspension";
|
||||
public const string START_CANCELLATION_MSG = "Starting domain name cancellation";
|
||||
public const string START_ROLLBACK_MSG = "Trying rollback operation";
|
||||
|
||||
public const string TLD_PROVISIONED_MSG = "Domain name has been provisioned";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Error Messages
|
||||
|
||||
public const string ERROR_UPDATE_USR_SETTINGS_MSG = "Could not update user settings";
|
||||
public const string ERROR_ADD_INTERNAL_DOMAIN = "Could not add internal domain";
|
||||
public const string ERROR_DOMAIN_QUOTA_EXCEEDED = "Domain quota has been exceeded in the customer's hosting plan";
|
||||
public const string ERROR_ROLLBACK_DOM_MSG = "Could not rollback added internal domain";
|
||||
|
||||
#endregion
|
||||
|
||||
protected DomainNameSvc GetDomainNameSvc(int serviceId)
|
||||
{
|
||||
// assemble svc instance
|
||||
DomainNameSvc domainSvc = ObjectUtils.FillObjectFromDataReader<DomainNameSvc>(
|
||||
EcommerceProvider.GetDomainNameSvc(SecurityContext.User.UserId, serviceId));
|
||||
// deserialize svc properties
|
||||
SecurityUtils.DeserializeGenericProfile(domainSvc.PropertyNames, domainSvc.PropertyValues, domainSvc);
|
||||
// return result
|
||||
return domainSvc;
|
||||
}
|
||||
|
||||
protected InvoiceItem GetDomainSvcSetupFee(DomainNameSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.Quantity = 1;
|
||||
line.UnitPrice = service.SetupFee;
|
||||
line.TypeName = "Setup Fee";
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
protected InvoiceItem GetDomainSvcFee(DomainNameSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.ServiceId = service.ServiceId;
|
||||
line.Quantity = 1;
|
||||
line.UnitPrice = service.RecurringFee;
|
||||
// define line type
|
||||
if (service.Status != ServiceStatus.Ordered)
|
||||
{
|
||||
line.TypeName = "Recurring Fee";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (service["SPF_ACTION"])
|
||||
{
|
||||
case DomainNameSvc.SPF_TRANSFER_ACTION:
|
||||
line.TypeName = String.Concat(Product.TOP_LEVEL_DOMAIN_NAME, " Transfer");
|
||||
break;
|
||||
case DomainNameSvc.SPF_REGISTER_ACTION:
|
||||
line.TypeName = String.Concat(Product.TOP_LEVEL_DOMAIN_NAME, " Registration");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#region IServiceProvisioning Members
|
||||
|
||||
public ServiceHistoryRecord[] GetServiceHistory(int serviceId)
|
||||
{
|
||||
List<ServiceHistoryRecord> history = ObjectUtils.CreateListFromDataReader<ServiceHistoryRecord>(
|
||||
EcommerceProvider.GetDomainNameSvcHistory(SecurityContext.User.UserId, serviceId));
|
||||
//
|
||||
if (history != null)
|
||||
return history.ToArray();
|
||||
//
|
||||
return new ServiceHistoryRecord[] { };
|
||||
}
|
||||
|
||||
public InvoiceItem[] CalculateInvoiceLines(int serviceId)
|
||||
{
|
||||
List<InvoiceItem> lines = new List<InvoiceItem>();
|
||||
//
|
||||
DomainNameSvc domainSvc = GetDomainNameSvc(serviceId);
|
||||
//
|
||||
if (domainSvc["SPF_ACTION"] != DomainNameSvc.SPF_UPDATE_NS_ACTION)
|
||||
{
|
||||
// domain svc fee
|
||||
lines.Add(GetDomainSvcFee(domainSvc));
|
||||
// setup fee
|
||||
if (domainSvc.SetupFee > 0M && domainSvc.Status == ServiceStatus.Ordered)
|
||||
lines.Add(GetDomainSvcSetupFee(domainSvc));
|
||||
}
|
||||
//
|
||||
return lines.ToArray();
|
||||
}
|
||||
|
||||
public Service GetServiceInfo(int serviceId)
|
||||
{
|
||||
return GetDomainNameSvc(serviceId);
|
||||
}
|
||||
|
||||
public int UpdateServiceInfo(Service serviceInfo)
|
||||
{
|
||||
DomainNameSvc domainSvc = (DomainNameSvc)serviceInfo;
|
||||
// serialize props & values
|
||||
string propertyNames = null;
|
||||
string propertyValues = null;
|
||||
SecurityUtils.SerializeGenericProfile(ref propertyNames, ref propertyValues, domainSvc);
|
||||
// update svc
|
||||
return EcommerceProvider.UpdateDomainNameSvc(SecurityContext.User.UserId, domainSvc.ServiceId,
|
||||
domainSvc.ProductId, (int)domainSvc.Status, domainSvc.DomainId, domainSvc.Fqdn,
|
||||
propertyNames, propertyValues);
|
||||
}
|
||||
|
||||
public int AddServiceInfo(string contractId, string currency, OrderItem orderItem)
|
||||
{
|
||||
string propertyNames = null;
|
||||
string propertyValues = null;
|
||||
// deserialize
|
||||
SecurityUtils.SerializeGenericProfile(ref propertyNames, ref propertyValues, orderItem);
|
||||
//
|
||||
return EcommerceProvider.AddDomainNameSvc(contractId, orderItem.ParentSvcId,
|
||||
orderItem.ProductId, orderItem.ItemName, orderItem.BillingCycle, currency, propertyNames, propertyValues);
|
||||
}
|
||||
|
||||
public GenericSvcResult ActivateService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
|
||||
// remeber svc state
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
|
||||
// concretize service to be provisioned
|
||||
DomainNameSvc domainSvc = (DomainNameSvc)context.ServiceInfo;
|
||||
// concretize parent service
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ParentSvcInfo;
|
||||
|
||||
try
|
||||
{
|
||||
// LOG INFO
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_ACTIVATE);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, domainSvc.ContractId);
|
||||
TaskManager.WriteParameter(SVC_PARAM, domainSvc.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, domainSvc.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// error: hosting addon should have parent svc assigned
|
||||
if (packageSvc == null || packageSvc.PackageId == 0)
|
||||
{
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = PARENT_SVC_NOT_FOUND_MSG;
|
||||
//
|
||||
result.ResultCode = EcommerceErrorCodes.ERROR_PARENT_SVC_NOT_FOUND;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// first of all - create internal domain in WebsitePanel
|
||||
if (domainSvc.Status == ServiceStatus.Ordered)
|
||||
{
|
||||
// create domain info object
|
||||
DomainInfo domain = ServerController.GetDomain(domainSvc.Fqdn);
|
||||
//
|
||||
if (domain != null)
|
||||
domainSvc.DomainId = domain.DomainId;
|
||||
//
|
||||
if (domain == null)
|
||||
{
|
||||
domain = new DomainInfo();
|
||||
domain.DomainName = domainSvc.Fqdn;
|
||||
domain.HostingAllowed = false;
|
||||
domain.PackageId = packageSvc.PackageId;
|
||||
// add internal domain
|
||||
domainSvc.DomainId = ServerController.AddDomain(domain);
|
||||
// check API result
|
||||
if (domainSvc.DomainId < 1)
|
||||
{
|
||||
// ASSEMBLE ERROR
|
||||
result.Succeed = false;
|
||||
// try to find corresponding error code->error message mapping
|
||||
if (ApiErrorCodesMap.ContainsKey(domainSvc.DomainId))
|
||||
result.Error = ApiErrorCodesMap[domainSvc.DomainId];
|
||||
else
|
||||
result.Error = ERROR_ADD_INTERNAL_DOMAIN;
|
||||
// copy result code
|
||||
result.ResultCode = domainSvc.DomainId;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update nameservers only
|
||||
if (domainSvc["SPF_ACTION"] == "UPDATE_NS")
|
||||
{
|
||||
// remove service here...
|
||||
ServiceController.DeleteCustomerService(domainSvc.ServiceId);
|
||||
//
|
||||
result.Succeed = true;
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// load registrar wrapper
|
||||
IDomainRegistrar registrar = (IDomainRegistrar)SystemPluginController.GetSystemPluginInstance(
|
||||
domainSvc.ContractId, domainSvc.PluginId, true);
|
||||
|
||||
#region Commented operations
|
||||
// prepare consumer account information
|
||||
/*CommandParams cmdParams = PrepeareAccountParams(context.ConsumerInfo);
|
||||
// copy svc properties
|
||||
foreach (string keyName in domainSvc.GetAllKeys())
|
||||
cmdParams[keyName] = domainSvc[keyName];
|
||||
|
||||
// check registrar requires sub-account to be created
|
||||
if (registrar.SubAccountRequired)
|
||||
{
|
||||
// 1. Load user's settings
|
||||
UserSettings userSettings = LoadUserSettings(context.ConsumerInfo.UserId, registrar.PluginName);
|
||||
// 2. Ensure user has account on registrar's side
|
||||
if (userSettings.SettingsArray == null || userSettings.SettingsArray.Length == 0)
|
||||
{
|
||||
// 3. Check account exists
|
||||
bool exists = registrar.CheckSubAccountExists(context.ConsumerInfo.Username, context.ConsumerInfo.Email);
|
||||
//
|
||||
AccountResult accResult = null;
|
||||
//
|
||||
if (!exists)
|
||||
{
|
||||
// 4. Create user account
|
||||
accResult = registrar.CreateSubAccount(cmdParams);
|
||||
// copy keys & values
|
||||
foreach (string keyName in accResult.AllKeys)
|
||||
{
|
||||
userSettings[keyName] = accResult[keyName];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4a. Get sub-account info
|
||||
accResult = registrar.GetSubAccount(context.ConsumerInfo.Username,
|
||||
context.ConsumerInfo.Email);
|
||||
//
|
||||
foreach (string keyName in accResult.AllKeys)
|
||||
userSettings[keyName] = accResult[keyName];
|
||||
}
|
||||
// 5. Update user settings
|
||||
int apiResult = UserController.UpdateUserSettings(userSettings);
|
||||
// check API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
// BUILD ERROR
|
||||
result.Error = ERROR_UPDATE_USR_SETTINGS_MSG;
|
||||
result.Succeed = false;
|
||||
result.ResultCode = apiResult;
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// ROLLBACK
|
||||
RollbackOperation(domainSvc.DomainId);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// copy registrar-specific data
|
||||
foreach (string[] pair in userSettings.SettingsArray)
|
||||
{
|
||||
// copy 2
|
||||
cmdParams[pair[0]] = pair[1];
|
||||
}
|
||||
}*/
|
||||
#endregion
|
||||
|
||||
// load NS settings
|
||||
PackageSettings nsSettings = PackageController.GetPackageSettings(packageSvc.PackageId, PackageSettings.NAME_SERVERS);
|
||||
// build name servers array
|
||||
string[] nameServers = null;
|
||||
if (!String.IsNullOrEmpty(nsSettings[PackageSettings.NAME_SERVERS]))
|
||||
nameServers = nsSettings[PackageSettings.NAME_SERVERS].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// register or renew domain
|
||||
if (domainSvc.Status == ServiceStatus.Ordered)
|
||||
// try to register domain
|
||||
registrar.RegisterDomain(domainSvc, context.ConsumerInfo, nameServers);
|
||||
else
|
||||
// try to renew domain
|
||||
registrar.RenewDomain(domainSvc, context.ConsumerInfo, nameServers);
|
||||
|
||||
// change svc status to active
|
||||
domainSvc.Status = ServiceStatus.Active;
|
||||
// update service info
|
||||
int updResult = UpdateServiceInfo(domainSvc);
|
||||
// check update result for errors
|
||||
if (updResult < 0)
|
||||
{
|
||||
// BUILD ERROR
|
||||
result.ResultCode = updResult;
|
||||
result.Succeed = false;
|
||||
result.Error = ERROR_SVC_UPDATE_MSG;
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// ROLLBACK
|
||||
RollbackOperation(domainSvc.DomainId);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
result.Succeed = true;
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ex);
|
||||
result.Succeed = false;
|
||||
// ROLLBACK
|
||||
RollbackOperation(result.ResultCode);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult SuspendService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
//
|
||||
result.Succeed = true;
|
||||
//
|
||||
DomainNameSvc service = (DomainNameSvc)context.ServiceInfo;
|
||||
service.Status = ServiceStatus.Suspended;
|
||||
//
|
||||
UpdateServiceInfo(service);
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult CancelService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
//
|
||||
result.Succeed = true;
|
||||
//
|
||||
DomainNameSvc service = (DomainNameSvc)context.ServiceInfo;
|
||||
service.Status = ServiceStatus.Cancelled;
|
||||
//
|
||||
UpdateServiceInfo(service);
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public void LogServiceUsage(ProvisioningContext context)
|
||||
{
|
||||
// concretize svc to be provisioned
|
||||
DomainNameSvc domainSvc = (DomainNameSvc)context.ServiceInfo;
|
||||
//
|
||||
base.LogServiceUsage(context.ServiceInfo, domainSvc.SvcCycleId,
|
||||
domainSvc.BillingPeriod, domainSvc.PeriodLength);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void RollbackOperation(int domainId)
|
||||
{
|
||||
if (domainId < 1)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// restore
|
||||
DomainNameSvc domainSvc = (DomainNameSvc)RestoreObjectState(SERVICE_INFO);
|
||||
|
||||
int apiResult = 0;
|
||||
|
||||
switch (domainSvc.Status)
|
||||
{
|
||||
// Service
|
||||
case ServiceStatus.Ordered:
|
||||
apiResult = ServerController.DeleteDomain(domainId);
|
||||
break;
|
||||
}
|
||||
|
||||
// check API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_ROLLBACK_DOM_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, apiResult);
|
||||
}
|
||||
|
||||
// rollback service changes in EC metabase
|
||||
apiResult = UpdateServiceInfo(domainSvc);
|
||||
// check API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_ROLLBACK_SVC_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, apiResult);
|
||||
// EXIT
|
||||
return;
|
||||
}
|
||||
//
|
||||
TaskManager.Write(ROLLBACK_SUCCEED_MSG);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TaskManager.WriteError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads user's plugin-specific settings
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="pluginName"></param>
|
||||
/// <returns></returns>
|
||||
private UserSettings LoadUserSettings(int userId, string pluginName)
|
||||
{
|
||||
// build settings name
|
||||
string settingsName = pluginName + "Settings";
|
||||
// load user settings
|
||||
UserSettings settings = UserController.GetUserSettings(userId, settingsName);
|
||||
// set settings name
|
||||
settings.SettingsName = settingsName;
|
||||
//
|
||||
return settings;
|
||||
}
|
||||
|
||||
private CommandParams PrepeareAccountParams(UserInfo userInfo)
|
||||
{
|
||||
CommandParams args = new CommandParams();
|
||||
|
||||
args[CommandParams.USERNAME] = userInfo.Username;
|
||||
args[CommandParams.PASSWORD] = userInfo.Password;
|
||||
args[CommandParams.FIRST_NAME] = userInfo.FirstName;
|
||||
args[CommandParams.LAST_NAME] = userInfo.LastName;
|
||||
args[CommandParams.EMAIL] = userInfo.Email;
|
||||
args[CommandParams.ADDRESS] = userInfo.Address;
|
||||
args[CommandParams.CITY] = userInfo.City;
|
||||
args[CommandParams.STATE] = userInfo.State;
|
||||
args[CommandParams.COUNTRY] = userInfo.Country;
|
||||
args[CommandParams.ZIP] = userInfo.Zip;
|
||||
args[CommandParams.PHONE] = userInfo.PrimaryPhone;
|
||||
args[CommandParams.FAX] = userInfo.Fax;
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,673 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
public class HostingAddonController : ServiceProvisioningBase, IServiceProvisioning
|
||||
{
|
||||
public const string SOURCE_NAME = "SPF_HOSTING_ADDN";
|
||||
|
||||
#region Trace Messages
|
||||
|
||||
public const string START_ACTIVATION_MSG = "Starting addon activation";
|
||||
public const string START_SUSPENSION_MSG = "Starting addon suspension";
|
||||
public const string START_CANCELLATION_MSG = "Starting addon cancellation";
|
||||
public const string START_ROLLBACK_MSG = "Trying rollback operation";
|
||||
|
||||
public const string ADDON_PROVISIONED_MSG = "Addon has been provisioned";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Error Messages
|
||||
|
||||
public const string ERROR_CREATE_ADDON_MSG = "Could not create hosting addon";
|
||||
|
||||
public const string ERROR_ACTIVATE_ADDON_MSG = "Could not activate hosting addon";
|
||||
public const string ERROR_SUSPEND_ADDON_MSG = "Could not suspend hosting addon";
|
||||
public const string ERROR_CANCEL_ADDON_MSG = "Could not cancel hosting addon";
|
||||
|
||||
public const string ERROR_ROLLBACK_ORDER_MSG = "Could not rollback operation and delete addon";
|
||||
public const string ERROR_ROLLBACK_MSG = "Could not rollback operation and revert addon state";
|
||||
|
||||
public const string ADDON_NOT_FOUND_MSG = "Could not find hosting addon";
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
protected HostingAddonSvc GetHostingAddonSvc(int serviceId)
|
||||
{
|
||||
return ObjectUtils.FillObjectFromDataReader<HostingAddonSvc>(
|
||||
EcommerceProvider.GetHostingAddonSvc(SecurityContext.User.UserId, serviceId));
|
||||
}
|
||||
|
||||
protected InvoiceItem GetAddonSvcFee(HostingAddonSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.ServiceId = service.ServiceId;
|
||||
line.Quantity = service.Quantity;
|
||||
line.UnitPrice = service.CyclePrice;
|
||||
|
||||
if (service.Recurring && service.Status != ServiceStatus.Ordered)
|
||||
line.TypeName = "Recurring Fee";
|
||||
else
|
||||
line.TypeName = Product.HOSTING_ADDON_NAME;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
protected InvoiceItem GetAddonSvcSetupFee(HostingAddonSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.Quantity = service.Quantity;
|
||||
line.UnitPrice = service.SetupFee;
|
||||
line.TypeName = "Setup Fee";
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#region IServiceProvisioning Members
|
||||
|
||||
public ServiceHistoryRecord[] GetServiceHistory(int serviceId)
|
||||
{
|
||||
List<ServiceHistoryRecord> history = ObjectUtils.CreateListFromDataReader<ServiceHistoryRecord>(
|
||||
EcommerceProvider.GetHostingAddonSvcHistory(SecurityContext.User.UserId, serviceId));
|
||||
//
|
||||
if (history != null)
|
||||
return history.ToArray();
|
||||
//
|
||||
return new ServiceHistoryRecord[] { };
|
||||
}
|
||||
|
||||
public InvoiceItem[] CalculateInvoiceLines(int serviceId)
|
||||
{
|
||||
List<InvoiceItem> lines = new List<InvoiceItem>();
|
||||
//
|
||||
HostingAddonSvc addonSvc = GetHostingAddonSvc(serviceId);
|
||||
// addon svc fee
|
||||
lines.Add(GetAddonSvcFee(addonSvc));
|
||||
// addon svc setup fee
|
||||
if (addonSvc.SetupFee > 0M && addonSvc.Status == ServiceStatus.Ordered)
|
||||
lines.Add(GetAddonSvcSetupFee(addonSvc));
|
||||
//
|
||||
return lines.ToArray();
|
||||
}
|
||||
|
||||
public int AddServiceInfo(string contractId, string currency, OrderItem orderItem)
|
||||
{
|
||||
// get hosting addon product
|
||||
HostingAddon addon = StorehouseController.GetHostingAddon(SecurityContext.User.UserId,
|
||||
orderItem.ProductId);
|
||||
// uncountable addons always have 1 for quantity
|
||||
int quantity = addon.Countable ? orderItem.Quantity : 1;
|
||||
// add hosting addon
|
||||
return EcommerceProvider.AddHostingAddonSvc(contractId, orderItem.ParentSvcId, orderItem.ProductId,
|
||||
quantity, orderItem.ItemName, orderItem.BillingCycle, currency);
|
||||
}
|
||||
|
||||
public Service GetServiceInfo(int serviceId)
|
||||
{
|
||||
return GetHostingAddonSvc(serviceId);
|
||||
}
|
||||
|
||||
public int UpdateServiceInfo(Service serviceInfo)
|
||||
{
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)serviceInfo;
|
||||
//
|
||||
return EcommerceProvider.UpdateHostingAddonSvc(SecurityContext.User.UserId, addonSvc.ServiceId,
|
||||
addonSvc.ProductId, addonSvc.ServiceName, (int)addonSvc.Status, addonSvc.PlanId,
|
||||
addonSvc.PackageAddonId, addonSvc.Recurring, addonSvc.DummyAddon);
|
||||
}
|
||||
|
||||
public GenericSvcResult ActivateService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
|
||||
// remeber svc state
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
|
||||
// concretize service to be provisioned
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)context.ServiceInfo;
|
||||
// concretize parent svc
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ParentSvcInfo;
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_ACTIVATE);
|
||||
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_ACTIVATION_MSG);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, addonSvc.ContractId);
|
||||
TaskManager.WriteParameter(SVC_PARAM, addonSvc.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, addonSvc.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// dummy addon should be just updated in metabase
|
||||
if (addonSvc.DummyAddon)
|
||||
goto UpdateSvcMetaInfo;
|
||||
|
||||
if (addonSvc.Status == ServiceStatus.Ordered)
|
||||
{
|
||||
// error: hosting addon should have parent svc assigned
|
||||
if (packageSvc == null || packageSvc.PackageId == 0)
|
||||
{
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = PARENT_SVC_NOT_FOUND_MSG;
|
||||
//
|
||||
result.ResultCode = EcommerceErrorCodes.ERROR_PARENT_SVC_NOT_FOUND;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// fill package add-on fields
|
||||
PackageAddonInfo addon = new PackageAddonInfo();
|
||||
//
|
||||
addon.PackageId = packageSvc.PackageId;
|
||||
//
|
||||
addon.PlanId = addonSvc.PlanId;
|
||||
// set addon quantity
|
||||
addon.Quantity = addonSvc.Quantity;
|
||||
//
|
||||
addon.StatusId = (int)PackageStatus.Active;
|
||||
//
|
||||
addon.PurchaseDate = DateTime.Now;
|
||||
|
||||
// Create hosting addon through WebsitePanel API
|
||||
PackageResult apiResult = PackageController.AddPackageAddon(addon);
|
||||
// Failed to create addon
|
||||
if (apiResult.Result < 1)
|
||||
{
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.ResultCode = apiResult.Result;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CREATE_ADDON_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
// store package id
|
||||
addonSvc.PackageAddonId = apiResult.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
// load package addon
|
||||
PackageAddonInfo addonInfo = PackageController.GetPackageAddon(addonSvc.PackageAddonId);
|
||||
// package addon not found
|
||||
if (addonInfo == null)
|
||||
{
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.ResultCode = EcommerceErrorCodes.ERROR_PCKG_ADDON_NOT_FOUND;
|
||||
//
|
||||
result.Error = ADDON_NOT_FOUND_MSG;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// workaround for bug in GetPackageAddon routine
|
||||
//addonInfo.PackageAddonId = addonSvc.PackageAddonId;
|
||||
// change package add-on status
|
||||
addonInfo.StatusId = (int)PackageStatus.Active;
|
||||
|
||||
// save hosting addon changes
|
||||
PackageResult apiResult = PackageController.UpdatePackageAddon(addonInfo);
|
||||
// check returned result
|
||||
if (apiResult.Result < 0)
|
||||
{
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.ResultCode = apiResult.Result;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_ACTIVATE_ADDON_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSvcMetaInfo:
|
||||
// update status only if necessary
|
||||
if (addonSvc.Status != ServiceStatus.Active)
|
||||
{
|
||||
// change service status to active
|
||||
addonSvc.Status = ServiceStatus.Active;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(addonSvc);
|
||||
// failed to update metabase
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ERROR_SVC_UPDATE_MSG;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(ADDON_PROVISIONED_MSG);
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult SuspendService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
//
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
// concretize service to be provisioned
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)context.ServiceInfo;
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_SUSPEND);
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_SUSPENSION_MSG);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, addonSvc.ContractId);
|
||||
TaskManager.WriteParameter(SVC_PARAM, addonSvc.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, addonSvc.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// dummy addon should be just updated in metabase
|
||||
if (addonSvc.DummyAddon)
|
||||
goto UpdateSvcMetaInfo;
|
||||
|
||||
PackageAddonInfo addonInfo = PackageController.GetPackageAddon(addonSvc.PackageAddonId);
|
||||
addonInfo.StatusId = (int)PackageStatus.Suspended;
|
||||
// suspend hosting addon
|
||||
int apiResult = PackageController.UpdatePackageAddon(addonInfo).Result;
|
||||
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
result.ResultCode = apiResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SUSPEND_ADDON_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// exit
|
||||
return result;
|
||||
}
|
||||
|
||||
UpdateSvcMetaInfo:
|
||||
// change addon status to Suspended
|
||||
addonSvc.Status = ServiceStatus.Suspended;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(addonSvc);
|
||||
//
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SVC_UPDATE_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(ADDON_PROVISIONED_MSG);
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult CancelService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
//
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
// concretize service to be provisioned
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)context.ServiceInfo;
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_CANCEL);
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_CANCELLATION_MSG);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, addonSvc.ContractId);
|
||||
TaskManager.WriteParameter(SVC_PARAM, addonSvc.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, addonSvc.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// dummy addon should be just updated in metabase
|
||||
if (addonSvc.DummyAddon)
|
||||
goto UpdateSvcMetaInfo;
|
||||
|
||||
PackageAddonInfo addonInfo = PackageController.GetPackageAddon(addonSvc.PackageAddonId);
|
||||
addonInfo.StatusId = (int)PackageStatus.Cancelled;
|
||||
// cancel hosting addon
|
||||
int apiResult = PackageController.UpdatePackageAddon(addonInfo).Result;
|
||||
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
result.ResultCode = apiResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CANCEL_ADDON_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// exit
|
||||
return result;
|
||||
}
|
||||
|
||||
UpdateSvcMetaInfo:
|
||||
// change addon status to Cancelled
|
||||
addonSvc.Status = ServiceStatus.Cancelled;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(addonSvc);
|
||||
//
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SVC_UPDATE_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(ADDON_PROVISIONED_MSG);
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(addonSvc.PackageAddonId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public void LogServiceUsage(ProvisioningContext context)
|
||||
{
|
||||
// concretize service to be logged
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)context.ServiceInfo;
|
||||
|
||||
// addon is recurring
|
||||
if (addonSvc.Recurring)
|
||||
{
|
||||
// log service usage
|
||||
base.LogServiceUsage(context.ServiceInfo, addonSvc.SvcCycleId,
|
||||
addonSvc.BillingPeriod, addonSvc.PeriodLength);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected void RollbackOperation(int packageAddonId)
|
||||
{
|
||||
// check input parameters first
|
||||
if (packageAddonId < 1)
|
||||
return; // exit
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
TaskManager.Write(START_ROLLBACK_MSG);
|
||||
// restore service
|
||||
HostingAddonSvc addonSvc = (HostingAddonSvc)RestoreObjectState(SERVICE_INFO);
|
||||
PackageAddonInfo addonInfo = PackageController.GetPackageAddon(addonSvc.PackageAddonId);
|
||||
//
|
||||
int apiResult = 0;
|
||||
|
||||
// during rollback addon should be reverted to its original state
|
||||
// compensation logic - revert back addon status
|
||||
switch (addonSvc.Status)
|
||||
{
|
||||
// Active State
|
||||
case ServiceStatus.Active:
|
||||
addonInfo.StatusId = (int)PackageStatus.Active;
|
||||
apiResult = PackageController.UpdatePackageAddon(addonInfo).Result;
|
||||
break;
|
||||
// Suspended State
|
||||
case ServiceStatus.Suspended:
|
||||
addonInfo.StatusId = (int)PackageStatus.Suspended;
|
||||
apiResult = PackageController.UpdatePackageAddon(addonInfo).Result;
|
||||
break;
|
||||
// Cancelled State
|
||||
case ServiceStatus.Cancelled:
|
||||
addonInfo.StatusId = (int)PackageStatus.Cancelled;
|
||||
apiResult = PackageController.UpdatePackageAddon(addonInfo).Result;
|
||||
break;
|
||||
// service has been just ordered & during rollback should be removed
|
||||
case ServiceStatus.Ordered:
|
||||
// compensation logic - remove created package
|
||||
apiResult = PackageController.DeletePackageAddon(packageAddonId);
|
||||
break;
|
||||
}
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
//
|
||||
if (addonSvc.Status == ServiceStatus.Ordered)
|
||||
TaskManager.WriteError(ERROR_ROLLBACK_ORDER_MSG);
|
||||
else
|
||||
TaskManager.WriteError(ERROR_ROLLBACK_MSG);
|
||||
//
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, apiResult);
|
||||
}
|
||||
|
||||
// rollback service changes in EC metabase
|
||||
apiResult = UpdateServiceInfo(addonSvc);
|
||||
// check API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_ROLLBACK_SVC_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, apiResult);
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
TaskManager.Write(ROLLBACK_SUCCEED_MSG);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TaskManager.WriteError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,676 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
public class HostingPackageController : ServiceProvisioningBase, IServiceProvisioning
|
||||
{
|
||||
//
|
||||
public const string SOURCE_NAME = "SPF_HOSTING_PKG";
|
||||
|
||||
#region Trace Messages
|
||||
|
||||
public const string START_ACTIVATION_MSG = "Starting package activation";
|
||||
public const string START_SUSPENSION_MSG = "Starting package suspension";
|
||||
public const string START_CANCELLATION_MSG = "Starting package cancellation";
|
||||
|
||||
public const string CREATE_PCKG_MSG = "Creating new hosting package";
|
||||
public const string CREATE_PCKG_ERROR_MSG = "Could not create hosting package";
|
||||
|
||||
public const string ERROR_ACTIVATE_PCKG_MSG = "Could not activate hosting package";
|
||||
public const string ERROR_SUSPEND_PCKG_MSG = "Could not suspend hosting package";
|
||||
public const string ERROR_CANCEL_PCKG_MSG = "Could not cancel hosting package";
|
||||
|
||||
public const string START_USR_ACTIVATION_MSG = "Activating service consumer account";
|
||||
public const string START_CHANGE_USR_ROLE_MSG = "Changing consumer user role";
|
||||
public const string ERROR_USR_ACTIVATION_MSG = "Could not activate consumer account";
|
||||
public const string ERROR_CHANGE_USR_ROLE_MSG = "Could not change consumer user role";
|
||||
|
||||
public const string PCKG_PROVISIONED_MSG = "Package has been provisioned";
|
||||
|
||||
#endregion
|
||||
|
||||
protected HostingPackageSvc GetHostingPackageSvc(int serviceId)
|
||||
{
|
||||
return ObjectUtils.FillObjectFromDataReader<HostingPackageSvc>(
|
||||
EcommerceProvider.GetHostingPackageSvc(SecurityContext.User.UserId, serviceId));
|
||||
}
|
||||
|
||||
protected InvoiceItem GetSetupFeeInvoiceLine(HostingPackageSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.Quantity = 1;
|
||||
line.UnitPrice = service.SetupFee;
|
||||
line.TypeName = "Setup Fee";
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
protected InvoiceItem GetRecurringFeeInvoiceLine(HostingPackageSvc service)
|
||||
{
|
||||
InvoiceItem line = new InvoiceItem();
|
||||
|
||||
line.ItemName = service.ServiceName;
|
||||
line.ServiceId = service.ServiceId;
|
||||
line.Quantity = 1;
|
||||
line.UnitPrice = service.RecurringFee;
|
||||
line.TypeName = (service.Status == ServiceStatus.Ordered) ? Product.HOSTING_PLAN_NAME : "Recurring Fee";
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#region IServiceProvisioning Members
|
||||
|
||||
public ServiceHistoryRecord[] GetServiceHistory(int serviceId)
|
||||
{
|
||||
List<ServiceHistoryRecord> history = ObjectUtils.CreateListFromDataReader<ServiceHistoryRecord>(
|
||||
EcommerceProvider.GetHostingPackageSvcHistory(SecurityContext.User.UserId, serviceId));
|
||||
|
||||
if (history != null)
|
||||
return history.ToArray();
|
||||
|
||||
return new ServiceHistoryRecord[] { };
|
||||
}
|
||||
|
||||
public InvoiceItem[] CalculateInvoiceLines(int serviceId)
|
||||
{
|
||||
List<InvoiceItem> lines = new List<InvoiceItem>();
|
||||
// load svc
|
||||
HostingPackageSvc packageSvc = GetHostingPackageSvc(serviceId);
|
||||
|
||||
// recurring fee
|
||||
lines.Add(GetRecurringFeeInvoiceLine(packageSvc));
|
||||
// setup fee
|
||||
if (packageSvc.Status == ServiceStatus.Ordered && packageSvc.SetupFee > 0M)
|
||||
lines.Add(GetSetupFeeInvoiceLine(packageSvc));
|
||||
|
||||
return lines.ToArray();
|
||||
}
|
||||
|
||||
public int AddServiceInfo(string contractId, string currency, OrderItem orderItem)
|
||||
{
|
||||
return EcommerceProvider.AddHostingPlanSvc(contractId, orderItem.ProductId,
|
||||
orderItem.ItemName, orderItem.BillingCycle, currency);
|
||||
}
|
||||
|
||||
public Service GetServiceInfo(int serviceId)
|
||||
{
|
||||
return GetHostingPackageSvc(serviceId);
|
||||
}
|
||||
|
||||
public int UpdateServiceInfo(Service service)
|
||||
{
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)service;
|
||||
//
|
||||
return EcommerceProvider.UpdateHostingPlanSvc(SecurityContext.User.UserId, packageSvc.ServiceId,
|
||||
packageSvc.ProductId, packageSvc.ServiceName, (int)packageSvc.Status, packageSvc.PlanId,
|
||||
packageSvc.PackageId, (int)packageSvc.UserRole, (int)packageSvc.InitialStatus);
|
||||
}
|
||||
|
||||
public GenericSvcResult ActivateService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
|
||||
//
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
//
|
||||
SaveObjectState(CONSUMER_INFO, context.ConsumerInfo);
|
||||
|
||||
// concretize service to be provisioned
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ServiceInfo;
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_ACTIVATE);
|
||||
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_ACTIVATION_MSG);
|
||||
TaskManager.WriteParameter(USERNAME_PARAM, context.ConsumerInfo[ContractAccount.USERNAME]);
|
||||
TaskManager.WriteParameter(SVC_PARAM, context.ServiceInfo.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, context.ServiceInfo.ServiceId);
|
||||
TaskManager.TaskParameters[SystemTaskParams.PARAM_SEND_EMAIL] = context.SendEmail;
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// 1. Hosting package is just ordered
|
||||
if (context.ServiceInfo.Status == ServiceStatus.Ordered && context.ContractInfo.CustomerId > 0)
|
||||
{
|
||||
// LOG INFO
|
||||
TaskManager.Write(CREATE_PCKG_MSG);
|
||||
// create new package
|
||||
PackageResult apiResult = PackageController.AddPackage(context.ContractInfo.CustomerId, packageSvc.PlanId,
|
||||
packageSvc.ServiceName, String.Empty, (int)packageSvc.InitialStatus, DateTime.Now, true, true);
|
||||
|
||||
// failed to instantiate package
|
||||
if (apiResult.Result <= 0)
|
||||
{
|
||||
result.ResultCode = apiResult.Result;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(CREATE_PCKG_ERROR_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
// save result PackageId
|
||||
packageSvc.PackageId = apiResult.Result;
|
||||
}
|
||||
else // 2. Package requires only to update its status
|
||||
{
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_ACTIVATION_MSG);
|
||||
|
||||
//
|
||||
int apiResult = PackageController.ChangePackageStatus(packageSvc.PackageId,
|
||||
PackageStatus.Active, false);
|
||||
//
|
||||
if (apiResult < 0)
|
||||
{
|
||||
result.ResultCode = apiResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_ACTIVATE_PCKG_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// check user role
|
||||
if (context.ContractInfo.CustomerId > 0)
|
||||
{
|
||||
UserInfo user = UserController.GetUserInternally(context.ContractInfo.CustomerId);
|
||||
// check user status
|
||||
//
|
||||
if (user.Status != UserStatus.Active)
|
||||
{
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_USR_ACTIVATION_MSG);
|
||||
|
||||
// trying to change user status
|
||||
int userResult = UserController.ChangeUserStatus(context.ContractInfo.CustomerId,
|
||||
UserStatus.Active);
|
||||
// failed to activate user account
|
||||
if (userResult < 0)
|
||||
{
|
||||
result.ResultCode = userResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_USR_ACTIVATION_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// check user role
|
||||
if (user.Role != packageSvc.UserRole)
|
||||
{
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_CHANGE_USR_ROLE_MSG);
|
||||
//
|
||||
user.Role = packageSvc.UserRole;
|
||||
// trying to change user role
|
||||
int roleResult = UserController.UpdateUser(user);
|
||||
// failed to change user role
|
||||
if (roleResult < 0)
|
||||
{
|
||||
result.ResultCode = roleResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
//
|
||||
TaskManager.WriteError(ERROR_CHANGE_USR_ROLE_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
// update plan status if necessary
|
||||
if (packageSvc.Status != ServiceStatus.Active)
|
||||
{
|
||||
// change service status to active
|
||||
packageSvc.Status = ServiceStatus.Active;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(packageSvc);
|
||||
|
||||
// error updating svc details
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SVC_UPDATE_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(PCKG_PROVISIONED_MSG);
|
||||
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult SuspendService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
|
||||
//
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
//
|
||||
SaveObjectState(CONSUMER_INFO, context.ConsumerInfo);
|
||||
|
||||
// concretize service to be provisioned
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ServiceInfo;
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_SUSPEND);
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_SUSPENSION_MSG);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, context.ConsumerInfo[ContractAccount.USERNAME]);
|
||||
TaskManager.WriteParameter(SVC_PARAM, context.ServiceInfo.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, context.ServiceInfo.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// suspend hosting package
|
||||
int apiResult = PackageController.ChangePackageStatus(packageSvc.PackageId,
|
||||
PackageStatus.Suspended, false);
|
||||
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
result.ResultCode = apiResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SUSPEND_PCKG_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// exit
|
||||
return result;
|
||||
}
|
||||
|
||||
// change service status to Suspended
|
||||
packageSvc.Status = ServiceStatus.Suspended;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(packageSvc);
|
||||
|
||||
//
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_SVC_UPDATE_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(PCKG_PROVISIONED_MSG);
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public GenericSvcResult CancelService(ProvisioningContext context)
|
||||
{
|
||||
GenericSvcResult result = new GenericSvcResult();
|
||||
|
||||
//
|
||||
SaveObjectState(SERVICE_INFO, context.ServiceInfo);
|
||||
//
|
||||
SaveObjectState(CONSUMER_INFO, context.ConsumerInfo);
|
||||
|
||||
// concretize service to be provisioned
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ServiceInfo;
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
TaskManager.StartTask(SystemTasks.SOURCE_ECOMMERCE, SystemTasks.SVC_CANCEL);
|
||||
// LOG INFO
|
||||
TaskManager.Write(START_CANCELLATION_MSG);
|
||||
TaskManager.WriteParameter(CONTRACT_PARAM, context.ConsumerInfo[ContractAccount.USERNAME]);
|
||||
TaskManager.WriteParameter(SVC_PARAM, context.ServiceInfo.ServiceName);
|
||||
TaskManager.WriteParameter(SVC_ID_PARAM, context.ServiceInfo.ServiceId);
|
||||
|
||||
// 0. Do security checks
|
||||
if (!CheckOperationClientPermissions(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_PERMISSIONS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
if (!CheckOperationClientStatus(result))
|
||||
{
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CLIENT_OPERATION_STATUS);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// cancel hosting package
|
||||
int apiResult = PackageController.ChangePackageStatus(packageSvc.PackageId,
|
||||
PackageStatus.Cancelled, false);
|
||||
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
//
|
||||
result.ResultCode = apiResult;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(ERROR_CANCEL_PCKG_MSG);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
|
||||
// change service status to Cancelled
|
||||
packageSvc.Status = ServiceStatus.Cancelled;
|
||||
// put data into metabase
|
||||
int svcResult = UpdateServiceInfo(packageSvc);
|
||||
|
||||
//
|
||||
if (svcResult < 0)
|
||||
{
|
||||
result.ResultCode = svcResult;
|
||||
//
|
||||
result.Error = ERROR_SVC_UPDATE_MSG;
|
||||
//
|
||||
result.Succeed = false;
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
// LOG ERROR
|
||||
TaskManager.WriteError(result.Error);
|
||||
TaskManager.WriteParameter(RESULT_CODE_PARAM, result.ResultCode);
|
||||
|
||||
// EXIT
|
||||
return result;
|
||||
}
|
||||
//
|
||||
SetOutboundParameters(context);
|
||||
// LOG INFO
|
||||
TaskManager.Write(PCKG_PROVISIONED_MSG);
|
||||
//
|
||||
result.Succeed = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError(ex);
|
||||
|
||||
// ROLLBACK CHANGES
|
||||
RollbackOperation(packageSvc.PackageId);
|
||||
|
||||
//
|
||||
result.Succeed = false;
|
||||
//
|
||||
result.Error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// complete task
|
||||
TaskManager.CompleteTask();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
public void LogServiceUsage(ProvisioningContext context)
|
||||
{
|
||||
// concretize service to be logged
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)context.ServiceInfo;
|
||||
|
||||
// log service usage
|
||||
base.LogServiceUsage(context.ServiceInfo, packageSvc.SvcCycleId,
|
||||
packageSvc.BillingPeriod, packageSvc.PeriodLength);
|
||||
}
|
||||
|
||||
protected void RollbackOperation(int packageId)
|
||||
{
|
||||
// check input parameters first
|
||||
if (packageId < 1)
|
||||
return; // exit
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
TaskManager.Write("Trying rollback operation");
|
||||
// restore service
|
||||
HostingPackageSvc packageSvc = (HostingPackageSvc)RestoreObjectState("ServiceInfo");
|
||||
// restore consumer
|
||||
UserInfo consumer = (UserInfo)RestoreObjectState("ConsumerInfo");
|
||||
|
||||
//
|
||||
int apiResult = 0;
|
||||
|
||||
// rollback consumer changes first
|
||||
apiResult = UserController.UpdateUser(consumer);
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError("Could not rollback consumer changes");
|
||||
//
|
||||
TaskManager.WriteParameter("ResultCode", apiResult);
|
||||
}
|
||||
|
||||
// during rollback package should be reverted to its original state
|
||||
// compensation logic - revert back package status
|
||||
switch (packageSvc.Status)
|
||||
{
|
||||
// Active State
|
||||
case ServiceStatus.Active:
|
||||
apiResult = PackageController.ChangePackageStatus(packageId, PackageStatus.Active, false);
|
||||
break;
|
||||
// Suspended State
|
||||
case ServiceStatus.Suspended:
|
||||
apiResult = PackageController.ChangePackageStatus(packageId, PackageStatus.Suspended, false);
|
||||
break;
|
||||
// Cancelled State
|
||||
case ServiceStatus.Cancelled:
|
||||
apiResult = PackageController.ChangePackageStatus(packageId, PackageStatus.Cancelled, false);
|
||||
break;
|
||||
// service has been just ordered & during rollback should be removed
|
||||
case ServiceStatus.Ordered:
|
||||
// compensation logic - remove created package
|
||||
apiResult = PackageController.DeletePackage(packageId);
|
||||
break;
|
||||
}
|
||||
// check WebsitePanel API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
//
|
||||
if (packageSvc.Status == ServiceStatus.Ordered)
|
||||
TaskManager.WriteError("Could not rollback operation and delete package");
|
||||
else
|
||||
TaskManager.WriteError("Could not rollback operation and revert package state");
|
||||
//
|
||||
TaskManager.WriteParameter("ResultCode", apiResult);
|
||||
}
|
||||
|
||||
// rollback service changes in EC metabase
|
||||
apiResult = UpdateServiceInfo(packageSvc);
|
||||
// check API result
|
||||
if (apiResult < 0)
|
||||
{
|
||||
//
|
||||
TaskManager.WriteError("Could not rollback service changes");
|
||||
//
|
||||
TaskManager.WriteParameter("ResultCode", apiResult);
|
||||
}
|
||||
|
||||
//
|
||||
TaskManager.Write("Rollback succeed");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TaskManager.WriteError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
public interface IServiceProvisioning
|
||||
{
|
||||
ServiceHistoryRecord[] GetServiceHistory(int serviceId);
|
||||
InvoiceItem[] CalculateInvoiceLines(int serviceId);
|
||||
ProvisioningContext GetProvisioningContext(int serviceId, bool sendEmail);
|
||||
int AddServiceInfo(string contractId, string currency, OrderItem orderItem);
|
||||
int UpdateServiceInfo(Service serviceInfo);
|
||||
Service GetServiceInfo(int serviceId);
|
||||
GenericSvcResult ActivateService(ProvisioningContext context);
|
||||
GenericSvcResult SuspendService(ProvisioningContext context);
|
||||
GenericSvcResult CancelService(ProvisioningContext context);
|
||||
void LogServiceUsage(ProvisioningContext context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.WebParts;
|
||||
using System.Web.UI.HtmlControls;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents context for provisioning controllers
|
||||
/// </summary>
|
||||
public class ProvisioningContext
|
||||
{
|
||||
private Contract contractInfo;
|
||||
private ContractAccount consumerInfo;
|
||||
private Service serviceInfo;
|
||||
private Service parentSvcInfo;
|
||||
private bool sendEmail;
|
||||
|
||||
public bool SendEmail
|
||||
{
|
||||
get { return sendEmail; }
|
||||
set { sendEmail = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets service consumer contract information
|
||||
/// </summary>
|
||||
public Contract ContractInfo
|
||||
{
|
||||
get { return contractInfo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets service consumer information
|
||||
/// </summary>
|
||||
public ContractAccount ConsumerInfo
|
||||
{
|
||||
get { return consumerInfo; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Get service information
|
||||
/// </summary>
|
||||
public Service ServiceInfo
|
||||
{
|
||||
get { return serviceInfo; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Get parent service information
|
||||
/// </summary>
|
||||
public Service ParentSvcInfo
|
||||
{
|
||||
get { return parentSvcInfo; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Ctor.
|
||||
/// </summary>
|
||||
/// <param name="service"></param>
|
||||
/// <param name="consumer"></param>
|
||||
public ProvisioningContext(Contract contract, Service service, ContractAccount consumer, Service parentSvc)
|
||||
{
|
||||
this.contractInfo = contract;
|
||||
this.serviceInfo = service;
|
||||
this.consumerInfo = consumer;
|
||||
this.parentSvcInfo = parentSvc;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,362 @@
|
|||
// Copyright (c) 2011, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
|
||||
using WebsitePanel.EnterpriseServer;
|
||||
|
||||
namespace WebsitePanel.Ecommerce.EnterpriseServer
|
||||
{
|
||||
public class Memento
|
||||
{
|
||||
private string mStateObjectType;
|
||||
private Hashtable mementoState;
|
||||
|
||||
public Memento()
|
||||
{
|
||||
//
|
||||
mementoState = new Hashtable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves object public properties state using reflection. Does not support indexed properties.
|
||||
/// </summary>
|
||||
/// <param name="objectKey"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SaveObjectState(object value)
|
||||
{
|
||||
//
|
||||
Type valueType = value.GetType();
|
||||
//
|
||||
PropertyInfo[] properties = valueType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
//
|
||||
if (properties != null && properties.Length > 0)
|
||||
{
|
||||
//
|
||||
Hashtable stateHash = new Hashtable();
|
||||
//
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
// copy property value
|
||||
if (property.GetIndexParameters() == null || property.GetIndexParameters().Length == 0)
|
||||
mementoState.Add(property.Name, property.GetValue(value, null));
|
||||
}
|
||||
// save object full-qualified name
|
||||
mStateObjectType = valueType.AssemblyQualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
public object RestoreObjectState()
|
||||
{
|
||||
// create object instance
|
||||
object keyObject = Activator.CreateInstance(Type.GetType(mStateObjectType));
|
||||
//
|
||||
Type objectType = keyObject.GetType();
|
||||
//
|
||||
PropertyInfo[] properties = objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
//
|
||||
if (properties != null && properties.Length > 0)
|
||||
{
|
||||
// load object state back
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
// restore property value back
|
||||
if (property.GetIndexParameters() == null || property.GetIndexParameters().Length == 0)
|
||||
property.SetValue(keyObject, mementoState[property.Name], null);
|
||||
}
|
||||
}
|
||||
//
|
||||
return keyObject;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ServiceProvisioningBase
|
||||
{
|
||||
// Contants
|
||||
public const string SERVICE_INFO = "ServiceInfo";
|
||||
public const string CONSUMER_INFO = "ConsumerInfo";
|
||||
|
||||
#region Error Messages
|
||||
|
||||
public const string ERROR_SVC_UPDATE_MSG = "Could not update service data";
|
||||
public const string PARENT_SVC_NOT_FOUND_MSG = "Could not find parent service assigned";
|
||||
public const string ERROR_ROLLBACK_SVC_MSG = "Could not rollback service changes";
|
||||
public const string ERROR_CLIENT_OPERATION_PERMISSIONS = "Account does not have enough permissions to do this operation";
|
||||
public const string ERROR_CLIENT_OPERATION_STATUS = "Account is demo or suspended and not allowed to do this operation";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Trace Messages
|
||||
|
||||
public const string ROLLBACK_SUCCEED_MSG = "Rollback succeed";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Trace Parameters
|
||||
|
||||
public const string CONTRACT_PARAM = "ContractID";
|
||||
public const string USERNAME_PARAM = "Username";
|
||||
public const string SVC_PARAM = "Service";
|
||||
public const string SVC_ID_PARAM = "ServiceID";
|
||||
public const string RESULT_CODE_PARAM = "ResultCode";
|
||||
public const string PCKG_PARAM = "Package";
|
||||
public const string PCKG_ID_PARAM = "PackageID";
|
||||
|
||||
#endregion
|
||||
|
||||
public bool CheckOperationClientPermissions(GenericSvcResult result)
|
||||
{
|
||||
// 1. Do security checks
|
||||
SecurityResult secResult = StorehouseController.CheckAccountIsAdminOrReseller();
|
||||
// ERROR
|
||||
if (!secResult.Success)
|
||||
{
|
||||
result.Succeed = false;
|
||||
result.ResultCode = secResult.ResultCode;
|
||||
//
|
||||
return false;
|
||||
}
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckOperationClientStatus(GenericSvcResult result)
|
||||
{
|
||||
// 2. Check account status
|
||||
SecurityResult secResult = StorehouseController.CheckAccountNotDemoAndActive();
|
||||
// ERROR
|
||||
if (!secResult.Success)
|
||||
{
|
||||
result.Succeed = false;
|
||||
result.ResultCode = secResult.ResultCode;
|
||||
//
|
||||
return false;
|
||||
}
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProvisioningContext GetProvisioningContext(int serviceId, bool sendEmail)
|
||||
{
|
||||
IServiceProvisioning controller = (IServiceProvisioning)this;
|
||||
Service serviceInfo = controller.GetServiceInfo(serviceId);
|
||||
Contract contractInfo = ContractSystem.ContractController.GetContract(serviceInfo.ContractId);
|
||||
ContractAccount consumerInfo = ContractSystem.ContractController.GetContractAccountSettings(
|
||||
serviceInfo.ContractId, true);
|
||||
// load parent svc
|
||||
Service parentSvcInfo = (serviceInfo.ParentId == 0) ? null :
|
||||
ServiceController.GetService(serviceInfo.ParentId);
|
||||
// return prepeared context
|
||||
ProvisioningContext ctx = new ProvisioningContext(contractInfo, serviceInfo, consumerInfo, parentSvcInfo);
|
||||
//
|
||||
ctx.SendEmail = sendEmail;
|
||||
//
|
||||
return ctx;
|
||||
}
|
||||
|
||||
//
|
||||
private Dictionary<string, Memento> undoSteps = new Dictionary<string, Memento>();
|
||||
|
||||
protected void SaveObjectState(string objectKey, object value)
|
||||
{
|
||||
//
|
||||
Memento memento = new Memento();
|
||||
//
|
||||
memento.SaveObjectState(value);
|
||||
//
|
||||
undoSteps.Add(objectKey, memento);
|
||||
}
|
||||
|
||||
protected object RestoreObjectState(string objectKey)
|
||||
{
|
||||
//
|
||||
if (!undoSteps.ContainsKey(objectKey))
|
||||
return null;
|
||||
//
|
||||
Memento memento = undoSteps[objectKey];
|
||||
//
|
||||
return memento.RestoreObjectState();
|
||||
}
|
||||
|
||||
protected void LogServiceUsage(Service service, int svcCycleId, string billingPeriod, int periodLength)
|
||||
{
|
||||
// define start date
|
||||
DateTime startDate = ServiceController.GetServiceSuspendDate(service.ServiceId);
|
||||
//
|
||||
DateTime endDate = startDate;
|
||||
//
|
||||
switch (billingPeriod)
|
||||
{
|
||||
case "day":
|
||||
endDate = startDate.AddDays(periodLength);
|
||||
break;
|
||||
case "month":
|
||||
endDate = endDate.AddMonths(periodLength);
|
||||
break;
|
||||
case "year":
|
||||
endDate = endDate.AddYears(periodLength);
|
||||
break;
|
||||
}
|
||||
// add service usage record
|
||||
EcommerceProvider.AddServiceUsageRecord(SecurityContext.User.UserId, service.ServiceId,
|
||||
svcCycleId, startDate, endDate);
|
||||
}
|
||||
|
||||
protected void SetOutboundParameters(ProvisioningContext context)
|
||||
{
|
||||
// set task outbound parameters
|
||||
TaskManager.TaskParameters[SystemTaskParams.PARAM_SERVICE] = context.ServiceInfo;
|
||||
TaskManager.TaskParameters[SystemTaskParams.PARAM_CONTRACT] = context.ContractInfo;
|
||||
TaskManager.TaskParameters[SystemTaskParams.PARAM_CONTRACT_ACCOUNT] = context.ConsumerInfo;
|
||||
TaskManager.TaskParameters[SystemTaskParams.PARAM_SEND_EMAIL] = context.SendEmail;
|
||||
}
|
||||
}
|
||||
|
||||
/*public abstract class ProvisioningController
|
||||
{
|
||||
// user info (context)
|
||||
// product general info
|
||||
// cart prov settings
|
||||
// product prov settings
|
||||
// product type prov settings
|
||||
//
|
||||
#region Private vars
|
||||
|
||||
private string notificationTemplate;
|
||||
private bool notificationLoaded;
|
||||
|
||||
private UserInfo userInfo;
|
||||
private Service serviceInfo;
|
||||
private KeyValueBunch serviceSettings;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
public string NotificationTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!notificationLoaded)
|
||||
|
||||
return notificationTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
public UserInfo UserInfo
|
||||
{
|
||||
get { return userInfo; }
|
||||
}
|
||||
|
||||
public Service ServiceInfo
|
||||
{
|
||||
get { return serviceInfo; }
|
||||
}
|
||||
|
||||
public KeyValueBunch ServiceSettings
|
||||
{
|
||||
get { return serviceSettings; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Abstract routines
|
||||
|
||||
//
|
||||
public abstract GenericSvcResult ActivateService(Service service);
|
||||
//
|
||||
public abstract GenericSvcResult SuspendService();
|
||||
//
|
||||
public abstract GenericSvcResult CancelService();
|
||||
//
|
||||
public abstract void RollbackOperation();
|
||||
|
||||
#endregion
|
||||
|
||||
protected ProvisioningController(Service serviceInfo)
|
||||
{
|
||||
this.serviceInfo = serviceInfo;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
// get user profile
|
||||
userInfo = UserController.GetUser(serviceInfo.UserId);
|
||||
}
|
||||
|
||||
protected DateTime CalculateNextSuspendDate(DateTime startDate, string cyclePeriod, int cycleLength)
|
||||
{
|
||||
// calculate next suspend date
|
||||
switch (cyclePeriod)
|
||||
{
|
||||
case "day":
|
||||
return startDate.AddDays(cycleLength);
|
||||
|
||||
case "month":
|
||||
return startDate.AddMonths(cycleLength);
|
||||
|
||||
case "year":
|
||||
return startDate.AddYears(cycleLength);
|
||||
}
|
||||
//
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public virtual void LoadProvisioningSettings()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// get service settings
|
||||
/*serviceSettings = ServiceController.GetServiceSettings(
|
||||
serviceInfo.SpaceId,
|
||||
serviceInfo.ServiceId
|
||||
);*/
|
||||
/*}
|
||||
|
||||
public virtual void SaveProvisioningSettings()
|
||||
{
|
||||
if (ServiceSettings.HasPendingChanges)
|
||||
{
|
||||
/*int result = ServiceController.SetServiceSettings(
|
||||
serviceInfo.SpaceId,
|
||||
serviceInfo.ServiceId,
|
||||
serviceSettings
|
||||
);
|
||||
|
||||
if (result < 0)
|
||||
throw new Exception("Unable to save provisioning settings. Status code: " + result);*/
|
||||
/*}
|
||||
}
|
||||
}*/
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue