Search in sources :

Example 1 with ProvUsage

use of org.ligoj.app.plugin.prov.model.ProvUsage in project plugin-prov by ligoj.

the class ProvQuoteInstanceResource method lookup.

private QuoteInstanceLookup lookup(final ProvQuote configuration, final double cpu, final int ram, final Boolean constant, final VmOs osName, final String type, final boolean ephemeral, final String location, final String usageName) {
    final String node = configuration.getSubscription().getNode().getId();
    final int subscription = configuration.getSubscription().getId();
    // Resolve
    final VmOs os = Optional.ofNullable(osName).map(VmOs::toPricingOs).orElse(null);
    // Resolve the location to use
    final String locationR = location == null ? configuration.getLocation().getName() : location;
    // Compute the rate to use
    final ProvUsage usage = usageName == null ? ObjectUtils.defaultIfNull(configuration.getUsage(), USAGE_DEFAULT) : resource.findConfiguredByName(usageRepository, usageName, subscription);
    final double rate = usage.getRate() / 100d;
    final int duration = usage.getDuration();
    // Resolve the required instance type
    final Integer typeId = type == null ? null : assertFound(itRepository.findByName(subscription, type), type).getId();
    // Return only the first matching instance
    // Template instance
    final QuoteInstanceLookup template = ipRepository.findLowestPrice(node, cpu, ram, constant, os, typeId, ephemeral, locationR, rate, duration, PageRequest.of(0, 1)).stream().findFirst().map(ip -> newPrice((ProvInstancePrice) ip[0], (double) ip[2])).orElse(null);
    // Custom instance
    final QuoteInstanceLookup custom = ipRepository.findLowestCustomPrice(node, Math.ceil(cpu), Math.ceil(ram / 1024), constant, os, locationR, PageRequest.of(0, 1)).stream().findFirst().map(ip -> newPrice((ProvInstancePrice) ip[0], rate * (double) ip[1])).orElse(null);
    // Select the best price term
    if (template == null) {
        return custom;
    }
    if (custom == null) {
        return template;
    }
    return custom.getCost() < template.getCost() ? custom : template;
}
Also used : CsvForBean(org.ligoj.bootstrap.core.csv.CsvForBean) Produces(javax.ws.rs.Produces) ProvInstancePriceRepository(org.ligoj.app.plugin.prov.dao.ProvInstancePriceRepository) Path(javax.ws.rs.Path) ProvUsageRepository(org.ligoj.app.plugin.prov.dao.ProvUsageRepository) Autowired(org.springframework.beans.factory.annotation.Autowired) StringUtils(org.apache.commons.lang3.StringUtils) ValidationJsonException(org.ligoj.bootstrap.core.validation.ValidationJsonException) MediaType(javax.ws.rs.core.MediaType) QueryParam(javax.ws.rs.QueryParam) ByteArrayInputStream(java.io.ByteArrayInputStream) Consumes(javax.ws.rs.Consumes) ProvLocation(org.ligoj.app.plugin.prov.model.ProvLocation) ProvInstanceTypeRepository(org.ligoj.app.plugin.prov.dao.ProvInstanceTypeRepository) DataTableAttributes(org.ligoj.bootstrap.core.json.datatable.DataTableAttributes) Map(java.util.Map) Multipart(org.apache.cxf.jaxrs.ext.multipart.Multipart) DefaultValue(javax.ws.rs.DefaultValue) Subscription(org.ligoj.app.model.Subscription) DescribedBean(org.ligoj.bootstrap.core.DescribedBean) DELETE(javax.ws.rs.DELETE) Context(javax.ws.rs.core.Context) Transactional(javax.transaction.Transactional) PageRequest(org.springframework.data.domain.PageRequest) Reader(java.io.Reader) StandardCharsets(java.nio.charset.StandardCharsets) ProvInstancePrice(org.ligoj.app.plugin.prov.model.ProvInstancePrice) Objects(java.util.Objects) ProvQuoteStorageRepository(org.ligoj.app.plugin.prov.dao.ProvQuoteStorageRepository) IOUtils(org.apache.commons.io.IOUtils) Slf4j(lombok.extern.slf4j.Slf4j) Optional(java.util.Optional) UriInfo(javax.ws.rs.core.UriInfo) TableItem(org.ligoj.bootstrap.core.json.TableItem) PathParam(javax.ws.rs.PathParam) GET(javax.ws.rs.GET) HashMap(java.util.HashMap) ArrayUtils(org.apache.commons.lang3.ArrayUtils) BooleanUtils(org.apache.commons.lang3.BooleanUtils) ProvQuoteInstance(org.ligoj.app.plugin.prov.model.ProvQuoteInstance) Function(java.util.function.Function) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ObjectUtils(org.apache.commons.lang3.ObjectUtils) Service(org.springframework.stereotype.Service) ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) POST(javax.ws.rs.POST) SequenceInputStream(java.io.SequenceInputStream) ProvQuoteInstanceRepository(org.ligoj.app.plugin.prov.dao.ProvQuoteInstanceRepository) IOException(java.io.IOException) InputStreamReader(java.io.InputStreamReader) ProvInstancePriceTermRepository(org.ligoj.app.plugin.prov.dao.ProvInstancePriceTermRepository) VmOs(org.ligoj.app.plugin.prov.model.VmOs) StringReader(java.io.StringReader) ProvInstancePriceTerm(org.ligoj.app.plugin.prov.model.ProvInstancePriceTerm) PUT(javax.ws.rs.PUT) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote) BufferedReader(java.io.BufferedReader) ProvInstanceType(org.ligoj.app.plugin.prov.model.ProvInstanceType) InputStream(java.io.InputStream) VmOs(org.ligoj.app.plugin.prov.model.VmOs) ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage)

Example 2 with ProvUsage

use of org.ligoj.app.plugin.prov.model.ProvUsage in project plugin-prov by ligoj.

the class ProvUsageResource method delete.

/**
 * Delete an usage. When the usage is associated to a quote or a resource, it is replaced by a <code>null</code>
 * reference.
 *
 * @param subscription
 *            The subscription identifier, will be used to filter the usages from the associated provider.
 * @param name
 *            The {@link ProvUsage} name.
 * @return The updated cost. Only relevant when at least one resource was associated to this usage.
 */
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Path("{subscription:\\d+}/usage/{name}")
public UpdatedCost delete(@PathParam("subscription") final int subscription, @PathParam("name") final String name) {
    final ProvUsage entity = resource.findConfiguredByName(repository, name, subscription);
    final ProvQuote quote = entity.getConfiguration();
    final UpdatedCost cost = new UpdatedCost();
    // Prepare the updated cost of updated instances
    final Map<Integer, FloatingCost> costs = cost.getRelatedCosts();
    cost.setRelatedCosts(costs);
    // Update the cost of all related instances
    if (entity.equals(quote.getUsage())) {
        // Update cost of all instances without explicit usage
        quote.setUsage(null);
        quote.getInstances().stream().filter(i -> i.getUsage() == null).forEach(i -> costs.put(i.getId(), instanceResource.addCost(i, instanceResource::refresh)));
    }
    quote.getInstances().stream().filter(i -> entity.equals(i.getUsage())).peek(i -> i.setUsage(null)).forEach(i -> costs.put(i.getId(), instanceResource.addCost(i, instanceResource::refresh)));
    // All references are deleted, delete the usage entity
    repository.delete(entity);
    // Save and update the costs
    cost.setTotalCost(resource.toFloatingCost(entity.getConfiguration()));
    return cost;
}
Also used : PathParam(javax.ws.rs.PathParam) POST(javax.ws.rs.POST) Context(javax.ws.rs.core.Context) Produces(javax.ws.rs.Produces) Transactional(javax.transaction.Transactional) GET(javax.ws.rs.GET) Path(javax.ws.rs.Path) ProvUsageRepository(org.ligoj.app.plugin.prov.dao.ProvUsageRepository) Autowired(org.springframework.beans.factory.annotation.Autowired) SubscriptionResource(org.ligoj.app.resource.subscription.SubscriptionResource) Function(java.util.function.Function) MediaType(javax.ws.rs.core.MediaType) Consumes(javax.ws.rs.Consumes) DataTableAttributes(org.ligoj.bootstrap.core.json.datatable.DataTableAttributes) Service(org.springframework.stereotype.Service) Map(java.util.Map) PUT(javax.ws.rs.PUT) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote) UriInfo(javax.ws.rs.core.UriInfo) ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) TableItem(org.ligoj.bootstrap.core.json.TableItem) PaginationJson(org.ligoj.bootstrap.core.json.PaginationJson) DELETE(javax.ws.rs.DELETE) ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) Consumes(javax.ws.rs.Consumes)

Example 3 with ProvUsage

use of org.ligoj.app.plugin.prov.model.ProvUsage in project plugin-prov by ligoj.

the class ProvQuoteInstanceResourceTest method lookupInstanceVariableDuration.

/**
 * Low usage rate, cheaper than 1y
 */
@Test
public void lookupInstanceVariableDuration() {
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev"), "C9", "instance2", 58.56, "on-demand2");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 11 month"), "C11", "instance2", 102.48, "1y");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 12 month"), "C11", "instance2", 102.48, "1y");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 13 month"), "C9", "instance2", 117.12, "on-demand2");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 23 month"), "C11", "instance2", 102.48, "1y");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 24 month"), "C11", "instance2", 102.48, "1y");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Full Time 25 month"), "C9", "instance2", 117.12, "on-demand2");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev 11 month"), "C9", "instance2", 29.28, "on-demand2");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev 12 month"), "C9", "instance2", 29.28, "on-demand2");
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev 13 month"), "C9", "instance2", 29.28, "on-demand2");
    ProvUsage usage = usageRepository.findByName("Dev 11 month");
    usage.setRate(90);
    usageRepository.saveAndFlush(usage);
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev 11 month"), "C9", "instance2", 105.408, "on-demand2");
    usage.setRate(98);
    usageRepository.saveAndFlush(usage);
    assertPrice(qiResource.lookup(subscription, 1, 2000, null, VmOs.LINUX, null, true, null, "Dev 11 month"), "C11", "instance2", 102.48, "1y");
}
Also used : ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) AbstractAppTest(org.ligoj.app.AbstractAppTest) Test(org.junit.jupiter.api.Test)

Example 4 with ProvUsage

use of org.ligoj.app.plugin.prov.model.ProvUsage in project plugin-prov by ligoj.

the class ProvUsageResource method create.

/**
 * Create the usage inside a quote. No cost are updated during this operation since this new {@link ProvUsage} is
 * not yet used.
 *
 * @param subscription
 *            The subscription identifier, will be used to filter the usages from the associated provider.
 * @param vo
 *            The quote usage.
 * @return The created usage identifier.
 */
@POST
@Path("{subscription:\\d+}/usage")
@Consumes(MediaType.APPLICATION_JSON)
public int create(@PathParam("subscription") final int subscription, final UsageEditionVo vo) {
    final ProvQuote configuration = resource.getQuoteFromSubscription(subscription);
    final ProvUsage entity = new ProvUsage();
    entity.setConfiguration(configuration);
    return saveOrUpdate(entity, vo).getId();
}
Also used : ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Example 5 with ProvUsage

use of org.ligoj.app.plugin.prov.model.ProvUsage in project plugin-prov by ligoj.

the class ProvUsageResource method saveOrUpdate.

/**
 * Save or update the given usage entity from the {@link UsageEditionVo}. The computed cost are recursively updated
 * from the related instances to the quote total cost.<br>
 * The cost of all instances related to this usage will be updated to get the new term and related price.<br>
 * An instance related to this usage is either an instance explicitly linked to this usage, either an instance
 * linked to a quote having this usage as default.
 */
private UpdatedCost saveOrUpdate(final ProvUsage entity, final UsageEditionVo vo) {
    // Check the associations and copy attributes to the entity
    entity.setRate(vo.getRate());
    entity.setDuration(vo.getDuration());
    entity.setName(vo.getName());
    final UpdatedCost cost = new UpdatedCost();
    if (entity.getId() != null) {
        final ProvQuote quote = entity.getConfiguration();
        // Prepare the updated cost of updated instances
        final Map<Integer, FloatingCost> costs = cost.getRelatedCosts();
        cost.setRelatedCosts(costs);
        // Update the cost of all related instances
        if (entity.equals(quote.getUsage())) {
            // Update cost of all instances without explicit usage
            quote.getInstances().stream().filter(i -> i.getUsage() == null).forEach(i -> costs.put(i.getId(), instanceResource.addCost(i, instanceResource::refresh)));
        }
        quote.getInstances().stream().filter(i -> entity.equals(i.getUsage())).forEach(i -> costs.put(i.getId(), instanceResource.addCost(i, instanceResource::refresh)));
        // Save and update the costs
        cost.setRelatedCosts(costs);
    }
    repository.saveAndFlush(entity);
    cost.setId(entity.getId());
    cost.setTotalCost(resource.toFloatingCost(entity.getConfiguration()));
    return cost;
}
Also used : PathParam(javax.ws.rs.PathParam) POST(javax.ws.rs.POST) Context(javax.ws.rs.core.Context) Produces(javax.ws.rs.Produces) Transactional(javax.transaction.Transactional) GET(javax.ws.rs.GET) Path(javax.ws.rs.Path) ProvUsageRepository(org.ligoj.app.plugin.prov.dao.ProvUsageRepository) Autowired(org.springframework.beans.factory.annotation.Autowired) SubscriptionResource(org.ligoj.app.resource.subscription.SubscriptionResource) Function(java.util.function.Function) MediaType(javax.ws.rs.core.MediaType) Consumes(javax.ws.rs.Consumes) DataTableAttributes(org.ligoj.bootstrap.core.json.datatable.DataTableAttributes) Service(org.springframework.stereotype.Service) Map(java.util.Map) PUT(javax.ws.rs.PUT) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote) UriInfo(javax.ws.rs.core.UriInfo) ProvUsage(org.ligoj.app.plugin.prov.model.ProvUsage) TableItem(org.ligoj.bootstrap.core.json.TableItem) PaginationJson(org.ligoj.bootstrap.core.json.PaginationJson) DELETE(javax.ws.rs.DELETE) ProvQuote(org.ligoj.app.plugin.prov.model.ProvQuote)

Aggregations

ProvUsage (org.ligoj.app.plugin.prov.model.ProvUsage)9 Consumes (javax.ws.rs.Consumes)4 POST (javax.ws.rs.POST)4 Path (javax.ws.rs.Path)4 Test (org.junit.jupiter.api.Test)4 AbstractAppTest (org.ligoj.app.AbstractAppTest)4 ProvQuote (org.ligoj.app.plugin.prov.model.ProvQuote)4 Map (java.util.Map)3 Function (java.util.function.Function)3 Transactional (javax.transaction.Transactional)3 DELETE (javax.ws.rs.DELETE)3 GET (javax.ws.rs.GET)3 PUT (javax.ws.rs.PUT)3 PathParam (javax.ws.rs.PathParam)3 Produces (javax.ws.rs.Produces)3 Context (javax.ws.rs.core.Context)3 MediaType (javax.ws.rs.core.MediaType)3 UriInfo (javax.ws.rs.core.UriInfo)3 ProvUsageRepository (org.ligoj.app.plugin.prov.dao.ProvUsageRepository)3 TableItem (org.ligoj.bootstrap.core.json.TableItem)3