com.thoughtworks.go.apiv5.plugininfos.PluginInfosControllerV5.java Source code

Java tutorial

Introduction

Here is the source code for com.thoughtworks.go.apiv5.plugininfos.PluginInfosControllerV5.java

Source

/*
 * Copyright 2019 ThoughtWorks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.thoughtworks.go.apiv5.plugininfos;

import com.thoughtworks.go.api.ApiController;
import com.thoughtworks.go.api.ApiVersion;
import com.thoughtworks.go.api.spring.ApiAuthenticationHelper;
import com.thoughtworks.go.apiv5.plugininfos.representers.PluginInfoRepresenter;
import com.thoughtworks.go.apiv5.plugininfos.representers.PluginInfosRepresenter;
import com.thoughtworks.go.config.exceptions.HttpException;
import com.thoughtworks.go.config.exceptions.RecordNotFoundException;
import com.thoughtworks.go.config.exceptions.UnprocessableEntityException;
import com.thoughtworks.go.plugin.access.ExtensionsRegistry;
import com.thoughtworks.go.plugin.domain.common.BadPluginInfo;
import com.thoughtworks.go.plugin.domain.common.CombinedPluginInfo;
import com.thoughtworks.go.plugin.infra.DefaultPluginManager;
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptor;
import com.thoughtworks.go.server.service.EntityHashingService;
import com.thoughtworks.go.server.service.plugins.builder.DefaultPluginInfoFinder;
import com.thoughtworks.go.spark.Routes;
import com.thoughtworks.go.spark.spring.SparkSpringController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import spark.Request;
import spark.Response;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.thoughtworks.go.api.util.HaltApiMessages.notFoundMessage;
import static java.util.stream.Collectors.toList;
import static spark.Spark.*;

@Component
public class PluginInfosControllerV5 extends ApiController implements SparkSpringController {

    private final ApiAuthenticationHelper apiAuthenticationHelper;
    private final EntityHashingService entityHashingService;
    private DefaultPluginManager defaultPluginManager;
    private ExtensionsRegistry extensionsRegistry;
    private DefaultPluginInfoFinder pluginInfoFinder;

    @Autowired
    public PluginInfosControllerV5(ApiAuthenticationHelper apiAuthenticationHelper,
            DefaultPluginInfoFinder pluginInfoFinder, EntityHashingService entityHashingService,
            DefaultPluginManager defaultPluginManager, ExtensionsRegistry extensionsRegistry) {
        super(ApiVersion.v5);
        this.apiAuthenticationHelper = apiAuthenticationHelper;
        this.pluginInfoFinder = pluginInfoFinder;
        this.entityHashingService = entityHashingService;
        this.defaultPluginManager = defaultPluginManager;
        this.extensionsRegistry = extensionsRegistry;
    }

    @Override
    public String controllerBasePath() {
        return Routes.PluginInfoAPI.BASE;
    }

    @Override
    public void setupRoutes() {
        path(controllerBasePath(), () -> {
            before("", mimeType, this::setContentType);
            before("/*", mimeType, this::setContentType);

            before("", this.mimeType, this.apiAuthenticationHelper::checkUserAnd403);
            before(Routes.PluginInfoAPI.ID, this.mimeType, this.apiAuthenticationHelper::checkUserAnd403);

            get("", mimeType, this::index);
            get(Routes.PluginInfoAPI.ID, mimeType, this::show);

            exception(HttpException.class, this::httpException);
        });
    }

    public String index(Request request, Response response) throws IOException {
        List<CombinedPluginInfo> pluginInfos = new ArrayList<>();
        String pluginType = request.queryParams("type");
        Boolean includeBad = Boolean.valueOf(request.queryParams("include_bad"));

        if (StringUtils.isNotBlank(pluginType)
                && !extensionsRegistry.allRegisteredExtensions().contains(pluginType)) {
            throw new UnprocessableEntityException(
                    String.format("Invalid plugin type '%s'. It has to be one of '%s'.", pluginType,
                            String.join(", ", extensionsRegistry.allRegisteredExtensions())));
        }

        Collection<CombinedPluginInfo> validPluginInfos = this.pluginInfoFinder.allPluginInfos(pluginType).stream()
                .filter(pluginInfo -> !hasUnsupportedExtensionType(pluginInfo)).collect(Collectors.toList());

        pluginInfos.addAll(validPluginInfos);

        if (includeBad) {
            List<BadPluginInfo> badPluginInfos = defaultPluginManager.plugins().stream()
                    .filter(GoPluginDescriptor::isInvalid).map(BadPluginInfo::new).collect(toList());

            pluginInfos.addAll(badPluginInfos);
        }

        pluginInfos
                .sort(Comparator.comparing((CombinedPluginInfo pluginInfos1) -> pluginInfos1.getDescriptor().id()));
        String etag = etagFor(pluginInfos);

        if (fresh(request, etag)) {
            return notModified(response);
        }
        setEtagHeader(response, etag);
        return writerForTopLevelObject(request, response,
                writer -> PluginInfosRepresenter.toJSON(writer, pluginInfos));

    }

    public String show(Request request, Response response) throws IOException {
        String pluginId = request.params("id");
        CombinedPluginInfo pluginInfo = this.pluginInfoFinder.pluginInfoFor(pluginId);

        if (pluginInfo == null) {
            GoPluginDescriptor pluginDescriptor = defaultPluginManager.getPluginDescriptorFor(pluginId);
            if (pluginDescriptor != null && pluginDescriptor.isInvalid()) {
                pluginInfo = new CombinedPluginInfo(new BadPluginInfo(pluginDescriptor));
            } else {
                throw new RecordNotFoundException(notFoundMessage());
            }
        }

        String etag = etagFor(pluginInfo);
        if (fresh(request, etag)) {
            return notModified(response);
        }

        setEtagHeader(response, etag);
        CombinedPluginInfo finalPluginInfo = pluginInfo;
        return writerForTopLevelObject(request, response,
                writer -> PluginInfoRepresenter.toJSON(writer, finalPluginInfo));
    }

    private boolean hasUnsupportedExtensionType(CombinedPluginInfo pluginInfo) {
        Set<String> extensionTypes = extensionsRegistry.allRegisteredExtensions();

        List<String> invalidExtensions = pluginInfo.extensionNames().stream()
                .filter(extensionName -> !extensionTypes.contains(extensionName)).collect(toList());
        return !invalidExtensions.isEmpty();
    }

    private String etagFor(CombinedPluginInfo pluginInfo) {
        return entityHashingService.md5ForEntity(pluginInfo);
    }

    private String etagFor(Collection<CombinedPluginInfo> pluginInfos) {
        return entityHashingService.md5ForEntity(pluginInfos);
    }
}