Search in sources :

Example 1 with PricePlan

use of io.codekvast.common.customer.PricePlan in project codekvast by crispab.

the class AgentServiceImpl method getConfig.

@Override
@Transactional(rollbackFor = Exception.class)
public GetConfigResponse1 getConfig(GetConfigRequest1 request) throws LicenseViolationException {
    CustomerData customerData = customerService.getCustomerDataByLicenseKey(request.getLicenseKey());
    boolean isAgentEnabled = updateAgentState(customerData, request.getJvmUuid());
    String publisherConfig = isAgentEnabled ? "enabled=true" : "enabled=false";
    PricePlan pp = customerData.getPricePlan();
    return GetConfigResponse1.builder().codeBasePublisherCheckIntervalSeconds(pp.getPublishIntervalSeconds()).codeBasePublisherConfig(publisherConfig).codeBasePublisherName("http").codeBasePublisherRetryIntervalSeconds(pp.getRetryIntervalSeconds()).configPollIntervalSeconds(pp.getPollIntervalSeconds()).configPollRetryIntervalSeconds(pp.getRetryIntervalSeconds()).customerId(customerData.getCustomerId()).invocationDataPublisherConfig(publisherConfig).invocationDataPublisherIntervalSeconds(pp.getPublishIntervalSeconds()).invocationDataPublisherName("http").invocationDataPublisherRetryIntervalSeconds(pp.getRetryIntervalSeconds()).build();
}
Also used : CustomerData(io.codekvast.common.customer.CustomerData) PricePlan(io.codekvast.common.customer.PricePlan) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with PricePlan

use of io.codekvast.common.customer.PricePlan in project codekvast by crispab.

the class DashboardServiceImpl method getMethodById.

@Override
@Transactional(readOnly = true)
public Optional<MethodDescriptor1> getMethodById(@NotNull Long methodId) {
    Long customerId = customerIdProvider.getCustomerId();
    PricePlan pricePlan = customerService.getCustomerDataByCustomerId(customerId).getPricePlan();
    MapSqlParameterSource params = new MapSqlParameterSource();
    params.addValue("customerId", customerId);
    params.addValue("methodId", methodId);
    MethodDescriptorRowCallbackHandler rch = new MethodDescriptorRowCallbackHandler(pricePlan);
    namedParameterJdbcTemplate.query("SELECT i.methodId, a.name AS appName, " + "  e.name AS envName, i.invokedAtMillis, i.createdAt, i.status, ad.collectedSince, ad.collectedTo, " + "  m.visibility, m.signature, m.declaringType, m.methodName, m.bridge, m.synthetic, m.modifiers,  m.packageName, ml.location, " + "  m.annotation AS methodAnnotation, ml.annotation AS methodLocationAnnotation, " + "  t.annotation AS typeAnnotation, p.annotation AS packageAnnotation " + "  FROM invocations i " + "    INNER JOIN applications a ON a.id = i.applicationId  " + "    INNER JOIN environments e ON e.id = i.environmentId  " + "    INNER JOIN methods m ON m.id = i.methodId  " + "    INNER JOIN types t ON t.name = m.declaringType " + "    INNER JOIN packages p ON p.name = m.packageName " + "    INNER JOIN application_descriptors ad ON ad.applicationId = i.applicationId AND ad.environmentId = i.environmentId " + "    LEFT JOIN method_locations ml ON m.id = ml.methodId  " + "  WHERE i.customerId = :customerId AND i.methodId = :methodId ", params, rch);
    return rch.getResult();
}
Also used : MapSqlParameterSource(org.springframework.jdbc.core.namedparam.MapSqlParameterSource) PricePlan(io.codekvast.common.customer.PricePlan) Transactional(org.springframework.transaction.annotation.Transactional)

Example 3 with PricePlan

use of io.codekvast.common.customer.PricePlan in project codekvast by crispab.

the class DashboardServiceImpl method getStatus.

@Override
@Transactional(readOnly = true)
public GetStatusResponse getStatus() {
    long startedAt = clock.millis();
    Long customerId = customerIdProvider.getCustomerId();
    CustomerData customerData = customerService.getCustomerDataByCustomerId(customerId);
    PricePlan pricePlan = customerData.getPricePlan();
    List<EnvironmentStatusDescriptor> environments = getEnvironments(customerId);
    List<ApplicationDescriptor2> applications = getApplications(customerId, pricePlan);
    List<AgentDescriptor> agents = getAgents(customerId, pricePlan.getPublishIntervalSeconds());
    Instant now = clock.instant();
    Instant collectionStartedAt = customerData.getCollectionStartedAt();
    Instant trialPeriodEndsAt = customerData.getTrialPeriodEndsAt();
    Duration trialPeriodDuration = collectionStartedAt == null || trialPeriodEndsAt == null ? null : Duration.between(collectionStartedAt, trialPeriodEndsAt);
    Duration trialPeriodProgress = trialPeriodDuration == null ? null : Duration.between(collectionStartedAt, now);
    Integer trialPeriodPercent = trialPeriodProgress == null ? null : Math.min(100, Math.toIntExact(trialPeriodProgress.toMillis() * 100L / trialPeriodDuration.toMillis()));
    return GetStatusResponse.builder().timestamp(startedAt).queryTimeMillis(clock.millis() - startedAt).pricePlan(pricePlan.getName()).retentionPeriodDays(pricePlan.getRetentionPeriodDays()).collectionResolutionSeconds(pricePlan.getPublishIntervalSeconds()).maxNumberOfAgents(pricePlan.getMaxNumberOfAgents()).maxNumberOfMethods(pricePlan.getMaxMethods()).collectedSinceMillis(pricePlan.adjustInstantToMillis(collectionStartedAt, clock)).trialPeriodEndsAtMillis(trialPeriodEndsAt == null ? null : trialPeriodEndsAt.toEpochMilli()).trialPeriodExpired(customerData.isTrialPeriodExpired(now)).trialPeriodPercent(trialPeriodPercent).numMethods(customerService.countMethods(customerId)).numAgents(agents.size()).numLiveAgents((int) agents.stream().filter(AgentDescriptor::isAgentAlive).count()).numLiveEnabledAgents((int) agents.stream().filter(AgentDescriptor::isAgentLiveAndEnabled).count()).environments(environments).applications(applications).agents(agents).build();
}
Also used : AgentDescriptor(io.codekvast.dashboard.dashboard.model.status.AgentDescriptor) CustomerData(io.codekvast.common.customer.CustomerData) Instant(java.time.Instant) Duration(java.time.Duration) EnvironmentStatusDescriptor(io.codekvast.dashboard.dashboard.model.status.EnvironmentStatusDescriptor) PricePlan(io.codekvast.common.customer.PricePlan) ApplicationDescriptor2(io.codekvast.dashboard.dashboard.model.status.ApplicationDescriptor2) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with PricePlan

use of io.codekvast.common.customer.PricePlan in project codekvast by crispab.

the class DashboardServiceImpl method getMethods2.

@Override
@Transactional(readOnly = true)
public GetMethodsResponse2 getMethods2(@Valid GetMethodsRequest request) {
    long startedAt = clock.millis();
    Long customerId = customerIdProvider.getCustomerId();
    PricePlan pricePlan = customerService.getCustomerDataByCustomerId(customerId).getPricePlan();
    MapSqlParameterSource params = new MapSqlParameterSource();
    params.addValue("latestCollectedSince", clock.instant().minus(request.getMinCollectedDays(), DAYS));
    params.addValue("now", new Timestamp(clock.millis()));
    params.addValue("customerId", customerId);
    String whereClause = "i.customerId = :customerId AND m.modifiers NOT LIKE '%abstract%'";
    String normalizedSignature = request.getNormalizedSignature();
    if (!normalizedSignature.equals("%")) {
        params.addValue("signature", normalizedSignature);
        whereClause += // Make it case-insensitive
        " AND m.signature LIKE :signature COLLATE utf8mb4_general_ci";
    }
    if (request.getApplications() != null && !request.getApplications().isEmpty()) {
        params.addValue("applicationIds", translateNamesToIds("applications", "name", request.getApplications()));
        whereClause += " AND i.applicationId IN (:applicationIds)";
    }
    if (request.getEnvironments() != null && !request.getEnvironments().isEmpty()) {
        params.addValue("environmentIds", translateNamesToIds("environments", "name", request.getEnvironments()));
        whereClause += " AND i.environmentId IN (:environmentIds)";
    }
    if (request.getLocations() != null && !request.getLocations().isEmpty()) {
        params.addValue("locationIds", translateNamesToIds("method_locations", "locationNoVersion", request.getLocations()));
        whereClause += " AND ml.id IN (:locationIds)";
    }
    String sql = "SELECT m.id, m.signature, " + "MAX(i.createdAt) AS latestCollectedSince, " + "MAX(i.status) AS status, " + "MAX(i.invokedAtMillis) AS lastInvokedAtMillis, " + "MAX(i.timestamp) AS lastPublishedAt, " + "m.annotation AS methodAnnotation, " + "ml.annotation AS methodLocationAnnotation, " + "p.annotation AS packageAnnotation, " + "t.annotation AS typeAnnotation " + "FROM invocations i " + "  INNER JOIN methods m ON i.methodId = m.id AND m.customerId = i.customerId " + "  INNER JOIN types t ON m.declaringType = t.name AND t.customerId = m.customerId " + "  INNER JOIN packages p ON m.packageName = p.name AND p.customerId = m.customerId " + "  LEFT JOIN method_locations ml ON ml.methodId = m.id AND ml.customerId = m.customerId " + "WHERE " + whereClause + " GROUP BY i.methodId " + "HAVING latestCollectedSince <= :latestCollectedSince " + "ORDER BY lastInvokedAtMillis ";
    List<MethodDescriptor2> methods = new ArrayList<>(request.getMaxResults());
    namedParameterJdbcTemplate.query(sql, params, rs -> {
        if (methods.size() >= request.getMaxResults()) {
            logger.trace("Ignoring row {}, since max result already achieved", rs.getRow());
            return;
        }
        String signature = rs.getString("signature");
        SignatureStatus2 status = SignatureStatus2.valueOf(rs.getString("status"));
        if (request.isSuppressUntrackedMethods() && !status.isTracked()) {
            logger.trace("Suppressing untracked method {} with status {}", signature, status);
            return;
        }
        Long lastInvokedAtMillis = pricePlan.adjustTimestampMillis(rs.getLong("lastInvokedAtMillis"), clock);
        if (lastInvokedAtMillis > request.getOnlyInvokedBeforeMillis()) {
            logger.trace("Suppressing method invoked after requested range");
            return;
        }
        if (lastInvokedAtMillis < request.getOnlyInvokedAfterMillis()) {
            logger.trace("Suppressing method invoked before requested range");
            return;
        }
        methods.add(MethodDescriptor2.builder().id(rs.getLong("id")).signature(signature).trackedPercent(status.isTracked() ? 100 : 0).collectedDays(pricePlan.adjustCollectedDays(getCollectedDays(rs.getTimestamp("latestCollectedSince")))).lastInvokedAtMillis(lastInvokedAtMillis).collectedToMillis(rs.getTimestamp("lastPublishedAt").getTime()).methodAnnotation(rs.getString("methodAnnotation")).methodLocationAnnotation(rs.getString("methodLocationAnnotation")).typeAnnotation(rs.getString("typeAnnotation")).packageAnnotation(rs.getString("packageAnnotation")).build());
    });
    methods.sort(Comparator.comparing(MethodDescriptor2::getSignature));
    long queryTimeMillis = clock.millis() - startedAt;
    logger.debug("Processed {} in {} ms.", request, queryTimeMillis);
    return GetMethodsResponse2.builder().timestamp(startedAt).request(request).numMethods(methods.size()).methods(methods).queryTimeMillis(queryTimeMillis).build();
}
Also used : SignatureStatus2(io.codekvast.javaagent.model.v2.SignatureStatus2) MapSqlParameterSource(org.springframework.jdbc.core.namedparam.MapSqlParameterSource) ArrayList(java.util.ArrayList) MethodDescriptor2(io.codekvast.dashboard.dashboard.model.methods.MethodDescriptor2) Timestamp(java.sql.Timestamp) PricePlan(io.codekvast.common.customer.PricePlan) Transactional(org.springframework.transaction.annotation.Transactional)

Example 5 with PricePlan

use of io.codekvast.common.customer.PricePlan in project codekvast by crispab.

the class CustomerServiceImpl method doAssertNumberOfMethods.

private void doAssertNumberOfMethods(CustomerData customerData, int numberOfMethods) {
    logger.debug("Asserting {} methods for {}", numberOfMethods, customerData);
    PricePlan pp = customerData.getPricePlan();
    if (numberOfMethods > pp.getMaxMethods()) {
        eventService.send(LicenseViolationEvent.builder().customerId(customerData.getCustomerId()).plan(pp.getName()).attemptedMethods(numberOfMethods).defaultMaxMethods(PricePlanDefaults.ofDatabaseName(pp.getName()).getMaxMethods()).effectiveMaxMethods(pp.getMaxMethods()).build());
        throw new LicenseViolationException(String.format("Too many methods: %d. The plan '%s' has a limit of %d methods", numberOfMethods, pp.getName(), pp.getMaxMethods()));
    }
}
Also used : LicenseViolationException(io.codekvast.common.customer.LicenseViolationException) PricePlan(io.codekvast.common.customer.PricePlan)

Aggregations

PricePlan (io.codekvast.common.customer.PricePlan)6 Transactional (org.springframework.transaction.annotation.Transactional)5 CustomerData (io.codekvast.common.customer.CustomerData)3 MapSqlParameterSource (org.springframework.jdbc.core.namedparam.MapSqlParameterSource)2 LicenseViolationException (io.codekvast.common.customer.LicenseViolationException)1 MethodDescriptor2 (io.codekvast.dashboard.dashboard.model.methods.MethodDescriptor2)1 AgentDescriptor (io.codekvast.dashboard.dashboard.model.status.AgentDescriptor)1 ApplicationDescriptor2 (io.codekvast.dashboard.dashboard.model.status.ApplicationDescriptor2)1 EnvironmentStatusDescriptor (io.codekvast.dashboard.dashboard.model.status.EnvironmentStatusDescriptor)1 SignatureStatus2 (io.codekvast.javaagent.model.v2.SignatureStatus2)1 Timestamp (java.sql.Timestamp)1 Duration (java.time.Duration)1 Instant (java.time.Instant)1 ArrayList (java.util.ArrayList)1 CacheEvict (org.springframework.cache.annotation.CacheEvict)1