<commit_before>/*
 * CODENVY CONFIDENTIAL
 * __________________
 *
 *  [2012] - [2015] Codenvy, S.A.
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Codenvy S.A. and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Codenvy S.A.
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Codenvy S.A..
 */
package com.codenvy.factory.workspace;

import com.codenvy.api.account.server.dao.AccountDao;
import com.codenvy.api.account.server.dao.Subscription;
import com.codenvy.api.core.ApiException;
import com.codenvy.api.core.notification.EventService;
import com.codenvy.api.core.notification.EventSubscriber;
import com.codenvy.api.core.rest.HttpJsonHelper;
import com.codenvy.api.core.rest.shared.dto.Link;
import com.codenvy.api.factory.FactoryBuilder;
import com.codenvy.api.factory.dto.Factory;
import com.codenvy.api.workspace.server.dao.Workspace;
import com.codenvy.api.workspace.server.dao.WorkspaceDao;
import com.codenvy.commons.lang.Pair;
import com.codenvy.dto.server.DtoFactory;
import com.codenvy.workspace.event.CreateWorkspaceEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.codenvy.commons.lang.Size.parseSizeToMegabytes;

/**
 * Set attributes to temporary workspaces that make runner/builder use custom resources for factory
 *
 * @author <NAME>
 */
@Singleton
public class FactoryWorkspaceResourceProvider implements EventSubscriber<CreateWorkspaceEvent> {
    private static final Logger  LOG                            = LoggerFactory.getLogger(FactoryWorkspaceResourceProvider.class);
    private static final String  RUNNER_LIFETIME                = "factory.runner.lifetime";
    private static final String  RUNNER_RAM                     = "factory.runner.ram";
    private static final String  BUILDER_EXECUTION_TIME         = "factory.builder.execution_time";
    private static final String  TRACKED_RUNNER_LIFETIME        = "factory.tracked.runner.lifetime";
    private static final String  TRACKED_BUILDER_EXECUTION_TIME = "factory.tracked.builder.execution_time";
    private static final String  TRACKED_RUNNER_RAM             = "factory.tracked.runner.ram";
    private static final Pattern ID_PATTERN                     = Pattern.compile("\\?id=([^&].*)");

    private final String runnerLifetime;
    private final String runnerRam;
    private final String builderExecutionTime;
    private final String trackedRunnerLifetime;
    private final String trackedBuilderExecutionTime;
    private final String trackedRunnerRam;

    private final String apiEndpoint;

    private final WorkspaceDao   workspaceDao;
    private final AccountDao     accountDao;
    private final EventService   eventService;
    private final FactoryBuilder factoryBuilder;

    @Inject
    public FactoryWorkspaceResourceProvider(@Named(TRACKED_RUNNER_LIFETIME) String trackedRunnerLifetime,
                                            @Named(TRACKED_BUILDER_EXECUTION_TIME) String trackedBuilderExecutionTime,
                                            @Nullable @Named(TRACKED_RUNNER_RAM) String trackedRunnerRam,
                                            @Nullable @Named(RUNNER_LIFETIME) String runnerLifetime,
                                            @Nullable @Named(RUNNER_RAM) String runnerRam,
                                            @Nullable @Named(BUILDER_EXECUTION_TIME) String builderExecutionTime,
                                            @Named("api.endpoint") String apiEndpoint,
                                            WorkspaceDao workspaceDao,
                                            AccountDao accountDao,
                                            EventService eventService,
                                            FactoryBuilder factoryBuilder) {
        this.trackedRunnerLifetime = trackedRunnerLifetime;
        this.trackedBuilderExecutionTime = trackedBuilderExecutionTime;
        this.trackedRunnerRam = trackedRunnerRam;
        this.runnerLifetime = runnerLifetime;
        this.runnerRam = runnerRam;
        this.builderExecutionTime = builderExecutionTime;
        this.apiEndpoint = apiEndpoint;
        this.workspaceDao = workspaceDao;
        this.eventService = eventService;
        this.factoryBuilder = factoryBuilder;
        this.accountDao = accountDao;
    }

    @PostConstruct
    private void subscribe() {
        eventService.subscribe(this);
    }

    @PreDestroy
    private void unsubscribe() {
        eventService.unsubscribe(this);
    }

    @Override
    public void onEvent(CreateWorkspaceEvent event) {
        Workspace createdWorkspace = event.getWorkspace();
        if (createdWorkspace.isTemporary()) {
            try {
                final Workspace workspace = workspaceDao.getById(createdWorkspace.getId());
                final Map<String, String> attributes = workspace.getAttributes();
                String factoryUrl = attributes.get("factoryUrl");
                try {
                    if (factoryUrl != null) {
                        factoryUrl = URLDecoder.decode(factoryUrl, "UTF-8");
                        final Matcher matcher = ID_PATTERN.matcher(factoryUrl);
                        Factory factory;
                        if (matcher.find()) {
                            final Link factoryObjectLink = DtoFactory.getInstance().createDto(Link.class)
                                                                     .withMethod("GET")
                                                                     .withHref(UriBuilder.fromUri(apiEndpoint)
                                                                                         .path("factory/" + matcher.group(1))
                                                                                         .build().toString());
                            factory = HttpJsonHelper.request(Factory.class, factoryObjectLink, Pair.of("validate", false));
                        } else {
                            factory = factoryBuilder.buildEncoded(URI.create(factoryUrl));
                        }

                        String accountId;
                        accountId = factory.getCreator() != null ? factory.getCreator().getAccountId() : null;
                        if (null != accountId) {
                            final List<Subscription> subscriptions = accountDao.getActiveSubscriptions(accountId, "Factory");
                            if (!subscriptions.isEmpty()) {
                                final Subscription subscription = subscriptions.iterator().next();
                                // factory workspace with subscription
                                attributes.put("codenvy:runner_lifetime", trackedRunnerLifetime);
                                attributes.put("codenvy:builder_execution_time", trackedBuilderExecutionTime);
                                attributes.put("codenvy:runner_ram",
                                               String.valueOf(parseSizeToMegabytes(subscription.getProperties().get("RAM"))));
                                attributes.put("codenvy:runner_infra", "paid");

                                workspaceDao.update(workspace.withAttributes(attributes));
                                return;
                            }
                        }<commit_msg>Reworked getting of subscription by service id<commit_after>/*
 * CODENVY CONFIDENTIAL
 * __________________
 *
 *  [2012] - [2015] Codenvy, S.A.
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Codenvy S.A. and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Codenvy S.A.
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Codenvy S.A..
 */
package com.codenvy.factory.workspace;

import com.codenvy.api.account.server.dao.AccountDao;
import com.codenvy.api.account.server.dao.Subscription;
import com.codenvy.api.core.ApiException;
import com.codenvy.api.core.notification.EventService;
import com.codenvy.api.core.notification.EventSubscriber;
import com.codenvy.api.core.rest.HttpJsonHelper;
import com.codenvy.api.core.rest.shared.dto.Link;
import com.codenvy.api.factory.FactoryBuilder;
import com.codenvy.api.factory.dto.Factory;
import com.codenvy.api.workspace.server.dao.Workspace;
import com.codenvy.api.workspace.server.dao.WorkspaceDao;
import com.codenvy.commons.lang.Pair;
import com.codenvy.dto.server.DtoFactory;
import com.codenvy.workspace.event.CreateWorkspaceEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.codenvy.commons.lang.Size.parseSizeToMegabytes;

/**
 * Set attributes to temporary workspaces that make runner/builder use custom resources for factory
 *
 * @author <NAME>
 */
@Singleton
public class FactoryWorkspaceResourceProvider implements EventSubscriber<CreateWorkspaceEvent> {
    private static final Logger  LOG                            = LoggerFactory.getLogger(FactoryWorkspaceResourceProvider.class);
    private static final String  RUNNER_LIFETIME                = "factory.runner.lifetime";
    private static final String  RUNNER_RAM                     = "factory.runner.ram";
    private static final String  BUILDER_EXECUTION_TIME         = "factory.builder.execution_time";
    private static final String  TRACKED_RUNNER_LIFETIME        = "factory.tracked.runner.lifetime";
    private static final String  TRACKED_BUILDER_EXECUTION_TIME = "factory.tracked.builder.execution_time";
    private static final String  TRACKED_RUNNER_RAM             = "factory.tracked.runner.ram";
    private static final Pattern ID_PATTERN                     = Pattern.compile("\\?id=([^&].*)");

    private final String runnerLifetime;
    private final String runnerRam;
    private final String builderExecutionTime;
    private final String trackedRunnerLifetime;
    private final String trackedBuilderExecutionTime;
    private final String trackedRunnerRam;

    private final String apiEndpoint;

    private final WorkspaceDao   workspaceDao;
    private final AccountDao     accountDao;
    private final EventService   eventService;
    private final FactoryBuilder factoryBuilder;

    @Inject
    public FactoryWorkspaceResourceProvider(@Named(TRACKED_RUNNER_LIFETIME) String trackedRunnerLifetime,
                                            @Named(TRACKED_BUILDER_EXECUTION_TIME) String trackedBuilderExecutionTime,
                                            @Nullable @Named(TRACKED_RUNNER_RAM) String trackedRunnerRam,
                                            @Nullable @Named(RUNNER_LIFETIME) String runnerLifetime,
                                            @Nullable @Named(RUNNER_RAM) String runnerRam,
                                            @Nullable @Named(BUILDER_EXECUTION_TIME) String builderExecutionTime,
                                            @Named("api.endpoint") String apiEndpoint,
                                            WorkspaceDao workspaceDao,
                                            AccountDao accountDao,
                                            EventService eventService,
                                            FactoryBuilder factoryBuilder) {
        this.trackedRunnerLifetime = trackedRunnerLifetime;
        this.trackedBuilderExecutionTime = trackedBuilderExecutionTime;
        this.trackedRunnerRam = trackedRunnerRam;
        this.runnerLifetime = runnerLifetime;
        this.runnerRam = runnerRam;
        this.builderExecutionTime = builderExecutionTime;
        this.apiEndpoint = apiEndpoint;
        this.workspaceDao = workspaceDao;
        this.eventService = eventService;
        this.factoryBuilder = factoryBuilder;
        this.accountDao = accountDao;
    }

    @PostConstruct
    private void subscribe() {
        eventService.subscribe(this);
    }

    @PreDestroy
    private void unsubscribe() {
        eventService.unsubscribe(this);
    }

    @Override
    public void onEvent(CreateWorkspaceEvent event) {
        Workspace createdWorkspace = event.getWorkspace();
        if (createdWorkspace.isTemporary()) {
            try {
                final Workspace workspace = workspaceDao.getById(createdWorkspace.getId());
                final Map<String, String> attributes = workspace.getAttributes();
                String factoryUrl = attributes.get("factoryUrl");
                try {
                    if (factoryUrl != null) {
                        factoryUrl = URLDecoder.decode(factoryUrl, "UTF-8");
                        final Matcher matcher = ID_PATTERN.matcher(factoryUrl);
                        Factory factory;
                        if (matcher.find()) {
                            final Link factoryObjectLink = DtoFactory.getInstance().createDto(Link.class)
                                                                     .withMethod("GET")
                                                                     .withHref(UriBuilder.fromUri(apiEndpoint)
                                                                                         .path("factory/" + matcher.group(1))
                                                                                         .build().toString());
                            factory = HttpJsonHelper.request(Factory.class, factoryObjectLink, Pair.of("validate", false));
                        } else {
                            factory = factoryBuilder.buildEncoded(URI.create(factoryUrl));
                        }

                        String accountId;
                        accountId = factory.getCreator() != null ? factory.getCreator().getAccountId() : null;
                        if (null != accountId) {
                            final Subscription factorySubscription = accountDao.getActiveSubscription(accountId, "Factory");
                            if (factorySubscription != null) {
                                // factory workspace with subscription
                                attributes.put("codenvy:runner_lifetime", trackedRunnerLifetime);
                                attributes.put("codenvy:builder_execution_time", trackedBuilderExecutionTime);
                                attributes.put("codenvy:runner_ram",
                                               String.valueOf(parseSizeToMegabytes(factorySubscription.getProperties().get("RAM"))));
                                attributes.put("codenvy:runner_infra", "paid");

                                workspaceDao.update(workspace.withAttributes(attributes));
                                return;
                            }
                        }
{'fraction_non_alphanumeric': 0.07535272818079661, 'fraction_numerical': 0.0014983143963041578, 'mean_word_length': 2.0093931993236898, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 74, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '265534', 'n_tokens_mistral': 3814, 'n_tokens_neox': 3722, 'n_words': 841}