com.vsct.dt.hesperides.resources.HesperidesApplicationResource.java Source code

Java tutorial

Introduction

Here is the source code for com.vsct.dt.hesperides.resources.HesperidesApplicationResource.java

Source

/*
 *
 *  * This file is part of the Hesperides distribution.
 *  * (https://github.com/voyages-sncf-technologies/hesperides)
 *  * Copyright (c) 2016 VSCT.
 *  *
 *  * Hesperides is free software: you can redistribute it and/or modify
 *  * it under the terms of the GNU General Public License as
 *  * published by the Free Software Foundation, version 3.
 *  *
 *  * Hesperides is distributed in the hope that it will be useful, but
 *  * WITHOUT ANY WARRANTY; without even the implied warranty of
 *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  * General Public License for more details.
 *  *
 *  * You should have received a copy of the GNU General Public License
 *  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 *
 */

package com.vsct.dt.hesperides.resources;

import com.codahale.metrics.annotation.Timed;
import com.vsct.dt.hesperides.applications.*;
import com.vsct.dt.hesperides.exception.runtime.*;
import com.vsct.dt.hesperides.exception.runtime.MissingResourceException;
import com.vsct.dt.hesperides.indexation.search.ApplicationSearch;
import com.vsct.dt.hesperides.security.UserContext;
import com.vsct.dt.hesperides.security.model.User;
import com.vsct.dt.hesperides.templating.models.HesperidesPropertiesModel;
import com.vsct.dt.hesperides.templating.models.KeyValuePropertyModel;
import com.vsct.dt.hesperides.templating.modules.ModuleKey;
import com.vsct.dt.hesperides.templating.modules.Modules;
import com.vsct.dt.hesperides.templating.platform.ApplicationData;
import com.vsct.dt.hesperides.templating.platform.ApplicationModuleData;
import com.vsct.dt.hesperides.templating.platform.PlatformData;
import com.vsct.dt.hesperides.templating.platform.TimeStampedPlatformData;
import com.vsct.dt.hesperides.util.HesperidesUtil;
import com.vsct.dt.hesperides.util.Release;
import com.vsct.dt.hesperides.util.WorkingCopy;
import com.vsct.dt.hesperides.util.converter.ApplicationConverter;
import com.vsct.dt.hesperides.util.converter.PlatformConverter;
import com.vsct.dt.hesperides.util.converter.PropertiesConverter;
import com.vsct.dt.hesperides.util.converter.TimeStampedPlatformConverter;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import io.dropwizard.auth.Auth;
import org.apache.http.util.Asserts;
import org.apache.lucene.search.Collector;
import com.google.common.collect.Sets;

import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static com.vsct.dt.hesperides.util.CheckArgument.isNonDisplayedChar;

/**
 * Created by william_montaz on 11/07/14.
 *
 * Modified by tidiane_sidibe on 05/08/2016 : adding the comment to event
 */
@Path("/applications")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Api("/applications")
public final class HesperidesApplicationResource extends BaseResource {

    private final Applications applications;
    private final Modules modules;
    private final ApplicationSearch applicationSearch;
    private final PlatformConverter platformConverter;
    private final PropertiesConverter propertiesConverter;
    final TimeStampedPlatformConverter timeStampedPlatformConverter;
    private ResponseConverter<PlatformData, Platform> responsePlatformConverter;
    private ResponseConverter<TimeStampedPlatformData, TimeStampedPlatform> responseTimeConverter;
    private ResponseConverter<ApplicationData, Application> responseApplicationConverter;

    private final HesperidesModuleResource moduleResource;

    public HesperidesApplicationResource(final Applications applications, final Modules modules,
            final ApplicationSearch applicationSearch,
            final TimeStampedPlatformConverter timeStampedPlatformConverter,
            final ApplicationConverter applicationDataConverter, final PropertiesConverter propertiesConverter,
            final HesperidesModuleResource moduleResource) {
        this.applications = applications;
        this.modules = modules;
        this.applicationSearch = applicationSearch;
        this.platformConverter = timeStampedPlatformConverter.getPlatformConverter();
        this.timeStampedPlatformConverter = timeStampedPlatformConverter;
        this.responsePlatformConverter = obj -> platformConverter.toPlatform(obj);
        this.responseTimeConverter = obj -> timeStampedPlatformConverter.toTimeStampedPlatform(obj);
        this.responseApplicationConverter = obj -> applicationDataConverter.toApplication(obj);
        this.propertiesConverter = propertiesConverter;

        this.moduleResource = moduleResource;
    }

    @Path("/using_module/{module}/{version}/{type}")
    @GET
    @Timed
    @ApiOperation("Get application using module")
    public Response getApplicationUsingModule(@Auth final User user, @PathParam("module") final String module,
            @PathParam("version") final String version, @PathParam("type") final String type) {

        return Response
                .ok(this.applications
                        .getApplicationsFromSelector(
                                data -> data.getModules().stream()
                                        .anyMatch(elem -> elem.getName().equals(module)
                                                && elem.getVersion().equals(version)
                                                && ((elem.isWorkingCopy() && type.equals("workingcopy"))
                                                        || (!elem.isWorkingCopy() && type.equals("release"))))))
                .build();
    }

    @Path("/{application_name}/platforms/{platform_name}/global_properties_usage")
    @GET
    @Timed
    @ApiOperation("Retrieve global properties usage in application")
    public Response getGlobalPropertiesUsage(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName) {

        Collection<PlatformData> l = this.applications
                .getApplicationsFromSelector(data -> data.getApplicationName().equals(applicationName)
                        && data.getPlatformName().equals(platformName));

        PlatformData p = l.stream().findFirst().get();

        Map<String, Set<HashMap>> usage = new HashMap<>();

        applications.getProperties(new PlatformKey(applicationName, platformName), "#").getKeyValueProperties()
                .stream().forEach(globalProp -> {

                    Set<HashMap> buffer = new HashSet<HashMap>();

                    p.getModules().stream().forEach(elem -> {

                        PlatformKey currentPlatformKey = new PlatformKey(applicationName, platformName);

                        Optional<HesperidesPropertiesModel> oModel;
                        HesperidesPropertiesModel model;

                        if (!elem.isWorkingCopy()) {
                            oModel = modules.getModel(new ModuleKey(elem.getName(), Release.of(elem.getVersion())));
                        } else {
                            oModel = modules
                                    .getModel(new ModuleKey(elem.getName(), WorkingCopy.of(elem.getVersion())));
                        }

                        if (oModel.isPresent()) {

                            model = oModel.get();
                            if (model.getKeyValueProperties().stream()
                                    .anyMatch(prop -> prop.getName().equals(globalProp.getName()))) {

                                buffer.add(new HashMap() {
                                    {
                                        put("path", elem.getPropertiesPath());
                                        put("inModel", true);
                                    }
                                });
                            }
                        } else {

                            model = null;
                        }

                        applications.getProperties(currentPlatformKey, elem.getPropertiesPath())
                                .getKeyValueProperties().stream().forEach(prop -> {

                                    if (prop.getName().equals(globalProp.getName())
                                            || prop.getValue().contains("{{" + globalProp.getName() + "}}")) {

                                        if (model == null) {

                                            buffer.add(new HashMap() {
                                                {
                                                    put("path", elem.getPropertiesPath());
                                                    put("inModel", false);
                                                }
                                            });
                                        } else {

                                            Boolean inModel = model.getKeyValueProperties().stream()
                                                    .anyMatch(mod -> prop.getName().equals(mod.getName()));

                                            buffer.add(new HashMap() {
                                                {
                                                    put("path", elem.getPropertiesPath());
                                                    put("inModel", inModel);
                                                }
                                            });
                                        }
                                    }
                                });
                    });
                    //            usage.put(globalProp.getName(), buffer.stream().distinct().collect(Collectors.toList()));
                    usage.put(globalProp.getName(), buffer);
                });

        return Response.ok(usage).build();
    }

    @Path("/{application_name}")
    @GET
    @Timed
    @ApiOperation("Get application with given name")
    public Response getApplication(@Auth final User user, @PathParam("application_name") final String name) {
        checkQueryParameterNotEmpty("application_name", name);

        return entityWithConverterOrNotFound(applications.getApplication(name), responseApplicationConverter);
    }

    @Path("/perform_search")
    @POST
    @Timed
    @ApiOperation("Get application by name")
    public Set<ApplicationListItem> searchApplications(@Auth final User user,
            @QueryParam("name") final String name) {
        checkQueryParameterNotEmpty("name", name);

        return applicationSearch.getApplicationsLike(name).stream()
                .map(applicationSearchResponse -> new ApplicationListItem(applicationSearchResponse.getName()))
                .collect(Collectors.toSet());
    }

    @Path("/platforms/perform_search")
    @POST
    @Timed
    @ApiOperation("Get all platform for a given application name")
    public Set<PlatformListItem> searchPlatforms(@Auth final User user,
            @QueryParam("applicationName") final String applicationName,
            @QueryParam("platformName") final String platformName) {
        checkQueryParameterNotEmpty("applicationName", applicationName);

        return applicationSearch.getAllPlatforms(applicationName, platformName).stream()
                .map(platformSearchResponse -> new PlatformListItem(platformSearchResponse.getName()))
                .collect(Collectors.toSet());
    }

    @Path("/{application_name}/platforms/{platform_name}")
    @GET
    @Timed
    @ApiOperation("Get platform for application with given name")
    public Response getPlatform(@Auth final User user, @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName, @QueryParam("timestamp") final Long timestamp) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        if (timestamp != null) {
            return entityWithConverterOrNotFound(applications.getPlatform(platformKey, timestamp),
                    responseTimeConverter);
        } else {
            return entityWithConverterOrNotFound(applications.getPlatform(platformKey), responsePlatformConverter);
        }
    }

    @Path("/{application_name}/platforms/{platform_name}")
    @DELETE
    @Timed
    @ApiOperation("Deletes a platform on a given app")
    public Response deletePlatform(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();
        applications.delete(platformKey);
        return Response.ok().build();
    }

    @Path("/{application_name}/platforms")
    @POST
    @Timed
    @ApiOperation("Create platform for application with given name, possibly from an existing platform")
    public Platform createPlatform(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @QueryParam("from_application") final String fromApplication,
            @QueryParam("from_platform") final String fromPlatform, @Valid final Platform platform) {

        if ((fromApplication == null || isNonDisplayedChar(fromApplication))
                && (fromPlatform == null || isNonDisplayedChar(fromPlatform))) {
            return platformConverter
                    .toPlatform(applications.createPlatform(platformConverter.toPlatformData(platform)));
        } else {
            PlatformKey fromPlatformKey = PlatformKey.withName(fromPlatform).withApplicationName(fromApplication)
                    .build();

            checkQueryParameterNotEmpty("from_application", fromApplication);
            checkQueryParameterNotEmpty("from_platform", fromPlatform);

            return platformConverter.toPlatform(applications.createPlatformFromExistingPlatform(
                    platformConverter.toPlatformData(platform), fromPlatformKey));
        }
    }

    @Path("/{application_name}/platforms")
    @PUT
    @Timed
    @ApiOperation("Update platform for application with given name")
    public Platform updatePlatform(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @QueryParam("copyPropertiesForUpgradedModules") final boolean copyPropertiesForUpgradedModules,
            @Valid final Platform platform) {
        return platformConverter.toPlatform(applications.updatePlatform(platformConverter.toPlatformData(platform),
                copyPropertiesForUpgradedModules));
    }

    @Path("/{application_name}/platforms/{platform_name}/properties")
    @GET
    @Timed
    @ApiOperation("Get properties with the given path in a platform")
    public Properties getProperties(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName, @QueryParam("path") final String path,
            @QueryParam("timestamp") final Long timestamp) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);
        checkQueryParameterNotEmpty("path", path);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        HesperidesPropertiesModel model = new HesperidesPropertiesModel(Sets.newHashSet(), Sets.newHashSet());

        if (path.length() > 1) {
            HesperidesUtil.ModuleInfo info = HesperidesUtil.moduleInfoFromPath(path);
            model = info.isRelease() ? this.moduleResource.getReleaseModel(user, info.getName(), info.getVersion())
                    : this.moduleResource.getWorkingCopyModel(user, info.getName(), info.getVersion());
        }

        return (timestamp != null)
                ? propertiesConverter
                        .toProperties(applications.getSecuredProperties(platformKey, path, timestamp, model))
                : propertiesConverter.toProperties(applications.getSecuredProperties(platformKey, path, model));
    }

    @Path("/{application_name}/platforms/{platform_name}/properties/instance_model")
    @GET
    @Timed
    @ApiOperation("Get properties with the given path in a platform")
    public InstanceModel getInstanceModel(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName, @QueryParam("path") final String path) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);
        checkQueryParameterNotEmpty("path", path);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();
        return applications.getInstanceModel(platformKey, path);
    }

    @Path("/{application_name}/platforms/{platform_name}/properties")
    @POST
    @Timed
    @ApiOperation("Save properties in a platform with the given path")
    public Properties saveProperties(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName, @QueryParam("path") final String path,
            @QueryParam("platform_vid") final Long platformID, //Using Long wrapper object helps preventing Java Primitive Default value of 0
            @QueryParam("comment") final String comment, @Valid final Properties properties) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);
        checkQueryParameterNotEmpty("path", path);
        checkQueryParameterNotEmpty("platform_vid", platformID);
        checkQueryParameterNotEmpty("comment", comment);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        //Filter properties to remove null or empty valorisations
        Properties propertiesCleaned;
        if (path.equals("#")) {
            propertiesCleaned = properties;
        } else {
            propertiesCleaned = properties.makeCopyWithoutNullOrEmptyValorisations();
        }

        return propertiesConverter.toProperties(applications.createOrUpdatePropertiesInPlatform(platformKey, path,
                propertiesConverter.toPropertiesData(propertiesCleaned), platformID, comment));
    }

    @Path("/{application_name}/platforms/{platform_name}/take_snapshot")
    @POST
    @Timed
    @ApiOperation("Take a snapshot of the platform")
    public Response takeSnapshot(@Auth final User user, @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        applications.takeSnapshot(platformKey);

        return Response.ok().build();
    }

    @Path("/{application_name}/platforms/{platform_name}/restore_snapshot")
    @POST
    @Timed
    @ApiOperation("Take a snapshot of the platform")
    public Platform restaureSnapshot(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName, @QueryParam("timestamp") final long timestamp) {

        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);
        checkQueryParameterNotEmpty("timestamp", timestamp);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        return platformConverter.toPlatform(applications.restoreSnapshot(platformKey, timestamp));
    }

    @Path("/{application_name}/platforms/{platform_name}/snapshots")
    @GET
    @Timed
    @ApiOperation("Get the list of timestamps corresponding to snapshots of the platform")
    public List<Long> getSnapshots(@Auth final User user,
            @PathParam("application_name") final String applicationName,
            @PathParam("platform_name") final String platformName) {
        checkQueryParameterNotEmpty("application_name", applicationName);
        checkQueryParameterNotEmpty("platform_name", platformName);

        PlatformKey platformKey = PlatformKey.withName(platformName).withApplicationName(applicationName).build();

        List<Long> snapshots = applications.getSnapshots(platformKey);
        Collections.sort(snapshots, (longA, longB) -> longB.compareTo(longA));
        return snapshots;
    }
}