/// <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 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 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 an entry in the webhookWebhookParameters table if it does not exist. /// </summary> /// <param name="webhookId">The ID of the webhook.</param> /// <param name="webhookParameterId">The ID of the webhookParameter.</param> /// <returns></returns> public async Task CreateJoinEntryAsync(long webhookId, long webhookParameterId) { if (await ExistsAsync(webhookId, webhookParameterId)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(WebhookWebhookParameter).Name, $"({webhookId}, {webhookParameterId})")); } WebhookWebhookParameter webhookWebhookParameter = new WebhookWebhookParameter { WebhookId = webhookId, WebhookParameterId = webhookParameterId }; _context.WebhookWebhookParameters.Add(webhookWebhookParameter); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(WebhookWebhookParameter).Name, $"(webhookId={webhookId}, webhookParameterId={webhookParameterId})")); }
/// <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); }
/// <summary> /// Uploads the given armTemplate as a JSON file in blob storage and records the URI to the /// created resrouce in the db. /// </summary> /// <param name="offerName">The name of the offer.</param> /// <param name="templateName">The name of the ARM template.</param> /// <param name="armTemplateJSON">The ARM Template's raw JSON data.</param> /// <returns>The created armTemplate db record.</returns> public async Task <ArmTemplate> CreateAsync(string offerName, string templateName, object armTemplateJSON) { if (armTemplateJSON is null) { throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplate).Name), UserErrorCode.PayloadNotProvided); } // Check that the offer does not already have an armTemplate with the same templateName if (await ExistsAsync(offerName, templateName)) { throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(ArmTemplate).Name, templateName, offerName: offerName)); } // Get the offer associated with the offerName provided var offer = await _offerService.GetAsync(offerName); // Get the container name associated with the offer var containerName = offer.ContainerName.ToString(); // Upload the armTemplateJSON as a file in blob storage and get the URL to the created resource var url = await uploadToBlobStorageAsync(containerName, GetArmTemplateFileName(templateName), armTemplateJSON.ToString()); _logger.LogInformation($"Arm template {templateName} in offer {offerName} is uploaded to {url}."); // Create the armTemplate to store in db ArmTemplate armTemplate = new ArmTemplate { OfferId = offer.Id, TemplateName = templateName, TemplateFilePath = url }; // Add armTemplate to db _context.ArmTemplates.Add(armTemplate); await _context._SaveChangesAsync(); _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(ArmTemplate).Name, templateName, offerName: offerName)); if (!await _armTemplateParameterService.ExistsAsync(offerName, "resourceGroupLocation")) { // Add parameter for resourceGroupLocation ArmTemplateParameter armParameter = new ArmTemplateParameter { OfferId = offer.Id, Name = "resourceGroupLocation", Type = "string", // TODO: do we need to indicate an incomplete parameter? Value = string.Empty }; await _armTemplateParameterService.CreateAsync(offerName, armTemplate.Id, armParameter); } if (!await _armTemplateParameterService.ExistsAsync(offerName, "entryPointUrl")) { // Add parameter for entryPointLink ArmTemplateParameter armParameter = new ArmTemplateParameter { OfferId = offer.Id, Name = "entryPointUrl", Type = "string", // TODO: do we need to indicate an incomplete parameter? Value = string.Empty }; await _armTemplateParameterService.CreateAsync(offerName, armTemplate.Id, armParameter); } // Add arm template parameters await CreateArmTemplateParameters(offer, armTemplateJSON, armTemplate.Id); return(armTemplate); }