public async Task <ActionResult> CreateOrUpdateAsync(string offerName, string templateName, [FromBody] object armTemplateJSON) { AADAuthHelper.VerifyUserAccess(this.HttpContext, _logger, true); if (armTemplateJSON == null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplate).Name), UserErrorCode.PayloadNotProvided); } ArmTemplate armTemplate = null; if (await _armTemplateService.ExistsAsync(offerName, templateName)) { // Update. Do not log armtemplatejson _logger.LogInformation(LoggingUtils.ComposeUpdateResourceMessage(typeof(ArmTemplateParameter).Name, templateName)); armTemplate = await _armTemplateService.UpdateAsync(offerName, templateName, armTemplateJSON); return(Ok(armTemplate)); } else { // Update. Do not log armtemplatejson _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(ArmTemplateParameter).Name, templateName)); armTemplate = await _armTemplateService.CreateAsync(offerName, templateName, armTemplateJSON); return(CreatedAtRoute(nameof(GetAsync) + nameof(ArmTemplate), new { OfferName = offerName, TemplateName = templateName }, armTemplate)); } }
/// <summary> /// Creates an aadSecretTmp object within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="aadSecretTmp">The aadSecretTmp object to create.</param> /// <returns>The created aadSecretTmp object.</returns> public async Task <AadSecretTmp> CreateAsync(string offerName, AadSecretTmp aadSecretTmp) { if (aadSecretTmp is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(AadSecretTmp).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an aadSecretTmp with the same name if (await ExistsAsync(offerName, aadSecretTmp.Name)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(AadSecretTmp).Name, aadSecretTmp.Name, offerName: offerName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(AadSecretTmp).Name, aadSecretTmp.Name, offerName: offerName, payload: JsonSerializer.Serialize(aadSecretTmp))); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Set the FK to offer aadSecretTmp.OfferId = offer.Id; // Add aadSecretTmp to db _context.AadSecretTmps.Add(aadSecretTmp); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(AadSecretTmp).Name, aadSecretTmp.Name, offerName: offerName)); return(aadSecretTmp); }
public async Task <SubscriptionParameter> CreateAsync(SubscriptionParameter subscriptionParameter) { if (subscriptionParameter is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(SubscriptionParameter).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an armTemplateParameter with the same name if (await ExistsAsync(subscriptionParameter.SubscriptionId, subscriptionParameter.Name)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(SubscriptionParameter).Name, subscriptionParameter.Name)); } if (!await _subscriptionService.ExistsAsync(subscriptionParameter.SubscriptionId)) { throw new ArgumentException("Subscription doesn't exist."); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(SubscriptionParameter).Name, subscriptionParameter.Name, payload: JsonSerializer.Serialize(subscriptionParameter))); // Add armTemplateParameter to db _context.SubscriptionParameters.Add(subscriptionParameter); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(SubscriptionParameter).Name, subscriptionParameter.Name)); return(subscriptionParameter); }
/// <summary> /// Creates a webhook within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="webhook">The webhook to create.</param> /// <returns>The created webhook.</returns> public async Task <Webhook> CreateAsync(string offerName, Webhook webhook) { if (webhook is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(Webhook).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have a webhook with the same webhookName if (await ExistsAsync(offerName, webhook.WebhookName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(Webhook).Name, webhook.WebhookName, offerName: offerName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(Webhook).Name, webhook.WebhookName, offerName: offerName, payload: JsonSerializer.Serialize(webhook))); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Set the FK to offer webhook.OfferId = offer.Id; // Add webhook to db _context.Webhooks.Add(webhook); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(Webhook).Name, webhook.WebhookName, offerName: offerName)); await CreateWebhookParameters(offerName, webhook); return(webhook); }
/// <summary> /// Creates a plan within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="plan">The plan to create.</param> /// <returns>The created plan.</returns> public async Task <Plan> CreateAsync(string offerName, Plan plan) { if (plan is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(Plan).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an plan with the same planUniqueName if (await ExistsAsync(offerName, plan.PlanName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(Plan).Name, plan.PlanName, offerName: offerName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(Plan).Name, plan.PlanName, offerName: offerName, payload: JsonSerializer.Serialize(plan))); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Set the FK to offer plan.OfferId = offer.Id; plan = await SetArmTemplateAndWebhookIds(offerName, plan); // Add plan to db _context.Plans.Add(plan); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(Plan).Name, plan.PlanName, offerName: offerName)); return(plan); }
/// <summary> /// Creates a restrictedUser within a plan within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="planUniqueName">The name of the plan.</param> /// <param name="restrictedUser">The restrictedUser to create.</param> /// <returns>The created restrictedUser.</returns> public async Task <RestrictedUser> CreateAsync(string offerName, string planUniqueName, RestrictedUser restrictedUser) { if (restrictedUser is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(RestrictedUser).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(RestrictedUser).Name, restrictedUser.TenantId.ToString(), offerName: offerName, planName: planUniqueName, payload: JsonSerializer.Serialize(restrictedUser))); // Get the plan associated with the offerName and planUniqueName provided var plan = await _planService.GetAsync(offerName, planUniqueName); // Set the FK to plan restrictedUser.PlanId = plan.Id; // Reset the PK (should not be modified in request) restrictedUser.Id = 0; // Add restrictedUser to db _context.RestrictedUsers.Add(restrictedUser); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(RestrictedUser).Name, restrictedUser.TenantId.ToString(), offerName: offerName, planName: planUniqueName)); return(restrictedUser); }
/// <summary> /// Creates a customMeter. /// </summary> /// <param name="offerName">The offer name of the customMeter.</param> /// <param name="meterName">The name of the customMeter.</param> /// <param name="customMeter">The customMeter to create.</param> /// <returns>The created customMeter.</returns> public async Task <CustomMeter> CreateAsync(string offerName, string meterName, CustomMeter customMeter) { if (customMeter is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(CustomMeter).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(CustomMeter).Name, customMeter.MeterName, offerName: offerName, payload: JsonSerializer.Serialize(customMeter))); // Check that an customMeter with the same name does not already exist if (await ExistsAsync(offerName, meterName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(CustomMeter).Name, customMeter.MeterName, offerName: offerName)); } var offer = await _offerService.GetAsync(offerName); var connector = await _telemetryDataconnectorService.GetAsync(customMeter.TelemetryDataConnectorName); customMeter.TelemetryDataConnectorId = connector.Id; customMeter.OfferId = offer.Id; using (var transaction = await _context.BeginTransactionAsync()) { // Not using subscriptionService here to avoid circular reference List <Subscription> subscriptionList = _context.Subscriptions.Where(s => s.OfferId == offer.Id && (s.Status == FulfillmentState.Subscribed.ToString() || s.Status == FulfillmentState.Suspended.ToString() || s.Status == FulfillmentState.PendingFulfillmentStart.ToString())).ToList(); _context.CustomMeters.Add(customMeter); await _context._SaveChangesAsync(); // Add customMeter to db foreach (var sub in subscriptionList) { bool isEnabled = sub.Status == FulfillmentState.Subscribed.ToString() || sub.Status == FulfillmentState.Suspended.ToString(); _context.SubscriptionCustomMeterUsages.Add(new SubscriptionCustomMeterUsage(customMeter.Id, sub.SubscriptionId, isEnabled)); } await _context._SaveChangesAsync(); transaction.Commit(); } _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(CustomMeter).Name, customMeter.MeterName, offerName: offerName)); return(customMeter); }
/// <summary> /// Creates a webhookParameter object within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="webhookId">The id of the webhook that the parameter is associated with.</param> /// <param name="webhookParameter">The webhookParameter to create.</param> /// <returns>The created webhookParameter.</returns> public async Task <WebhookParameter> CreateAsync(string offerName, long webhookId, WebhookParameter webhookParameter) { if (webhookParameter is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(WebhookParameter).Name), UserErrorCode.PayloadNotProvided); } if (ExpressionEvaluationUtils.ReservedParameterNames.Contains(webhookParameter.Name)) { _logger.LogInformation($"Webhook {webhookId} is referencing system parameter {webhookParameter.Name}"); return(webhookParameter); //throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(WebhookParameter).Name, // webhookParameter.Name, offerName: offerName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(WebhookParameter).Name, webhookParameter.Name, offerName: offerName, payload: JsonSerializer.Serialize(webhookParameter))); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Check if the WebhookParameter already exists if (await ExistsAsync(offerName, webhookParameter.Name)) { // Just create a new join entry to keep track of the fact that this Webhook is using this parameter WebhookParameter webhookParameterDb = await GetAsync(offerName, webhookParameter.Name); await _webhookWebhookParameterService.CreateJoinEntryAsync(webhookId, webhookParameterDb.Id); return(webhookParameterDb); } // Set the FK to offer webhookParameter.OfferId = offer.Id; // Add webhookParameter to db _context.WebhookParameters.Add(webhookParameter); await _context._SaveChangesAsync(); await _webhookWebhookParameterService.CreateJoinEntryAsync(webhookId, webhookParameter.Id); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(WebhookParameter).Name, webhookParameter.Name, offerName: offerName)); return(webhookParameter); }
/// <summary> /// Creates a customMeterDimension within a plan within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="planUniqueName">The name of the plan.</param> /// <param name="customMeterDimension">The customMeterDimension object to create.</param> /// <returns>The created customMeterDimension.</returns> public async Task <CustomMeterDimension> CreateAsync(string offerName, string planUniqueName, CustomMeterDimension customMeterDimension) { if (customMeterDimension is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(CustomMeterDimension).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage( typeof(CustomMeterDimension).Name, customMeterDimension.Id.ToString(), offerName: offerName, planName: planUniqueName, payload: JsonSerializer.Serialize(customMeterDimension))); // Get the plan associated with the offerName and planUniqueName provided var plan = await _planService.GetAsync(offerName, planUniqueName); // Set the FK to plan customMeterDimension.PlanId = plan.Id; // Set the FK to customMeter customMeterDimension.MeterId = (await _customMeterService.GetAsync(customMeterDimension.MeterName)).Id; // Reset the PK (should not be modified in request) customMeterDimension.Id = 0; // Add customMeterDimension to db _context.CustomMeterDimensions.Add(customMeterDimension); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage( typeof(ArmTemplateParameter).Name, customMeterDimension.Id.ToString(), offerName: offerName, planName: planUniqueName)); return(customMeterDimension); }
/// <summary> /// Creates a subscriptionCustomMeterUsage. /// </summary> /// <param name="subscriptionId">The subscription id.</param> /// <param name="meterName">The name of the SubscriptionCustomMeterUsage to update.</param> /// <param name="subscriptionCustomMeterUsage">The subscriptionCustomMeterUsage to create.</param> /// <returns>The created subscriptionCustomMeterUsage.</returns> public async Task <SubscriptionCustomMeterUsage> CreateAsync( Guid subscriptionId, string meterName, SubscriptionCustomMeterUsage subscriptionCustomMeterUsage) { if (subscriptionCustomMeterUsage is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(SubscriptionCustomMeterUsage).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage( typeof(SubscriptionCustomMeterUsage).Name, subscriptionCustomMeterUsage.MeterId.ToString(), subscriptionId: subscriptionCustomMeterUsage.SubscriptionId, payload: JsonSerializer.Serialize(subscriptionCustomMeterUsage))); var subscription = await _subscriptionService.GetAsync(subscriptionId); var customMeter = await _customMeterService.GetAsync(subscription.OfferName, meterName); // Check that an SubscriptionCustomMeterUsage with the same name does not already exist if (await ExistsAsync(subscriptionId, meterName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage( typeof(SubscriptionCustomMeterUsage).Name, customMeter.MeterName, subscriptionId: subscriptionId)); } // Add customMeter to db _context.SubscriptionCustomMeterUsages.Add(subscriptionCustomMeterUsage); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(SubscriptionCustomMeterUsage).Name, meterName, subscriptionId: subscriptionId)); return(subscriptionCustomMeterUsage); }
/// <summary> /// Creates a TelemetryDataConnector. /// </summary> /// <param name="offerName">The name of the TelemetryDataConnector.</param> /// <param name="connector">The TelemetryDataConnector to create.</param> /// <returns>The created TelemetryDataConnector.</returns> public async Task <TelemetryDataConnector> CreateAsync(string name, TelemetryDataConnector connector) { if (connector is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(TelemetryDataConnector).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(TelemetryDataConnector).Name, name, payload: JsonSerializer.Serialize(connector))); // Check that an TelemetryDataConnector with the same name does not already exist if (await ExistsAsync(name)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(TelemetryDataConnector).Name, name)); } _context.TelemetryDataConnectors.Add(connector); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(TelemetryDataConnector).Name, name)); return(connector); }
/// <summary> /// Creates an ipConfig within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="ipConfig">The ipConfig to create.</param> /// <returns>The created ipConfig.</returns> public async Task <IpConfig> CreateAsync(string offerName, IpConfig ipConfig) { if (ipConfig is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(IpConfig).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an ipConfig with the same name if (await ExistsAsync(offerName, ipConfig.Name)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(IpConfig).Name, ipConfig.Name, offerName: offerName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(IpConfig).Name, ipConfig.Name, offerName: offerName, payload: JsonSerializer.Serialize(ipConfig))); // Validate that the values provided for the IpConfig are syntactically and logically correct ipConfig = validateIpConfig(ipConfig); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Set the FK to offer ipConfig.OfferId = offer.Id; // Add ipConfig to db _context.IpConfigs.Add(ipConfig); await _context._SaveChangesAsync(); // Process the IpBlocks await ProcessIpBlocks(ipConfig.IpBlocks, ipConfig.Id); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(IpConfig).Name, ipConfig.Name, offerName: offerName)); return(ipConfig); }
/// <summary> /// Creates an offer. /// </summary> /// <param name="offer">The offer to create.</param> /// <returns>The created offer.</returns> public async Task <Offer> CreateAsync(Offer offer) { if (offer is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(Offer).Name), UserErrorCode.PayloadNotProvided); } // Check that an offer with the same name does not already exist if (await ExistsAsync(offer.OfferName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(Offer).Name, offer.OfferName)); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(Offer).Name, offer.OfferName, payload: JsonSerializer.Serialize(offer))); // Generate a ContainerName for the offer offer.ContainerName = Guid.NewGuid(); // Update the offer status offer.Status = nameof(OfferStatus.Draft); // Update the offer created time offer.CreatedTime = DateTime.UtcNow; // Update the offer last updated time offer.LastUpdatedTime = offer.CreatedTime; // Add offer to db _context.Offers.Add(offer); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(Offer).Name, offer.OfferName)); return(offer); }
/// <summary> /// Creates a customMeter. /// </summary> /// <param name="customMeter">The customMeter to create.</param> /// <returns>The created customMeter.</returns> public async Task <CustomMeter> CreateAsync(CustomMeter customMeter) { if (customMeter is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(CustomMeter).Name), UserErrorCode.PayloadNotProvided); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(CustomMeter).Name, customMeter.MeterName, payload: JsonSerializer.Serialize(customMeter))); // Check that an customMeter with the same name does not already exist if (await ExistsAsync(customMeter.MeterName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(CustomMeter).Name, customMeter.MeterName)); } // Add customMeter to db _context.CustomMeters.Add(customMeter); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(CustomMeter).Name, customMeter.MeterName)); return(customMeter); }
/// <summary> /// Creates an offerParameter within an offer. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="offerParameter">The offerParameter to create.</param> /// <returns>The created offerParameter.</returns> public async Task <OfferParameter> CreateAsync(string offerName, OfferParameter offerParameter) { if (offerParameter is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(OfferParameter).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an offerParameter with the same parameterName if (await ExistsAsync(offerName, offerParameter.ParameterName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(OfferParameter).Name, offerParameter.ParameterName, offerName: offerName)); } if (ExpressionEvaluationUtils.ReservedParameterNames.Contains(offerParameter.ParameterName)) { throw new LunaConflictUserException($"Parameter {offerParameter.ParameterName} is reserved. Please use a different name."); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(OfferParameter).Name, offerParameter.ParameterName, offerName: offerName, payload: JsonSerializer.Serialize(offerParameter))); // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Set the FK to offer offerParameter.OfferId = offer.Id; // Add offerParameter to db _context.OfferParameters.Add(offerParameter); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(OfferParameter).Name, offerParameter.ParameterName, offerName: offerName)); return(offerParameter); }
/// <summary> /// Creates a subscription within a plan within an offer. /// </summary> /// <param name="subscription">The subscription to create.</param> /// <returns>The created subscription.</returns> public async Task <Subscription> CreateAsync(Subscription subscription) { if (subscription is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(Subscription).Name), UserErrorCode.PayloadNotProvided); } if (await ExistsAsync(subscription.SubscriptionId)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(Subscription).Name, subscription.SubscriptionId.ToString())); } _logger.LogInformation(LoggingUtils.ComposeCreateResourceMessage(typeof(Subscription).Name, subscription.Name, offerName: subscription.OfferName, planName: subscription.PlanName, payload: JsonSerializer.Serialize(subscription))); var offerParameters = await _offerParameterService.GetAllAsync(subscription.OfferName); foreach (var param in offerParameters) { // Check if value of all offer parameters are provided with correct type if (subscription.InputParameters.Where(x => x.Name.Equals(param.ParameterName) && x.Type.Equals(param.ValueType)).Count() < 1) { throw new LunaBadRequestUserException($"Value of parameter {param.ParameterName} is not provided, or the type doesn't match.", UserErrorCode.ParameterNotProvided); } } // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(subscription.OfferName); // Get the plan associated with the planUniqueName provided var plan = await _planService.GetAsync(subscription.OfferName, subscription.PlanName); // Set the FK to offer subscription.OfferId = offer.Id; // Set the FK to plan subscription.PlanId = plan.Id; // Always set quantity to 1 to walkaround a marketplace service bug subscription.Quantity = 1; // Set the created time subscription.CreatedTime = DateTime.UtcNow; subscription.Status = nameof(FulfillmentState.PendingFulfillmentStart); subscription.ProvisioningStatus = nameof(ProvisioningState.ProvisioningPending); subscription.ProvisioningType = nameof(ProvisioningType.Subscribe); subscription.RetryCount = 0; List <CustomMeter> customMeterList = await _customMeterService.GetAllAsync(offer.OfferName); using (var transaction = await _context.BeginTransactionAsync()) { // Add subscription to db _context.Subscriptions.Add(subscription); await _context._SaveChangesAsync(); // Add subscription parameters foreach (var param in subscription.InputParameters) { param.SubscriptionId = subscription.SubscriptionId; _context.SubscriptionParameters.Add(param); } await _context._SaveChangesAsync(); foreach (var meter in customMeterList) { _context.SubscriptionCustomMeterUsages.Add(new SubscriptionCustomMeterUsage(meter.Id, subscription.SubscriptionId)); } await _context._SaveChangesAsync(); transaction.Commit(); } _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(Subscription).Name, subscription.Name, offerName: subscription.OfferName, planName: subscription.PlanName)); return(subscription); }