blob: 5cb3a64292cc490d93d5dad5cbdb6dca9eb5201b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
import com.epam.dlab.backendapi.service.EndpointService;
import com.epam.dlab.backendapi.service.ImageExploratoryService;
import com.epam.dlab.backendapi.service.ProjectService;
import com.epam.dlab.backendapi.util.RequestBuilder;
import com.epam.dlab.constants.ServiceConsts;
import com.epam.dlab.dto.UserInstanceDTO;
import com.epam.dlab.dto.UserInstanceStatus;
import com.epam.dlab.dto.exploratory.ExploratoryStatusDTO;
import com.epam.dlab.dto.exploratory.ImageStatus;
import com.epam.dlab.exceptions.ResourceAlreadyExistException;
import com.epam.dlab.exceptions.ResourceNotFoundException;
import com.epam.dlab.model.ResourceType;
import com.epam.dlab.model.exploratory.Image;
import com.epam.dlab.model.library.Library;
import com.epam.dlab.rest.client.RESTService;
import com.epam.dlab.rest.contracts.ExploratoryAPI;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@Singleton
@Slf4j
public class ImageExploratoryServiceImpl implements ImageExploratoryService {
private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s";
private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s";
@Inject
private ExploratoryDAO exploratoryDAO;
@Inject
private ImageExploratoryDao imageExploratoryDao;
@Inject
private ExploratoryLibDAO libDAO;
@Inject
@Named(ServiceConsts.PROVISIONING_SERVICE_NAME)
private RESTService provisioningService;
@Inject
private RequestBuilder requestBuilder;
@Inject
private EndpointService endpointService;
@Inject
private ProjectService projectService;
@Override
public String createImage(UserInfo user, String project, String exploratoryName, String imageName, String imageDescription) {
ProjectDTO projectDTO = projectService.get(project);
UserInstanceDTO userInstance = exploratoryDAO.fetchRunningExploratoryFields(user.getName(), project, exploratoryName);
if (imageExploratoryDao.exist(imageName, userInstance.getProject())) {
log.error(String.format(IMAGE_EXISTS_MSG, imageName, userInstance.getProject()));
throw new ResourceAlreadyExistException(String.format(IMAGE_EXISTS_MSG, imageName, userInstance.getProject()));
}
final List<Library> libraries = libDAO.getLibraries(user.getName(), project, exploratoryName);
imageExploratoryDao.save(Image.builder()
.name(imageName)
.description(imageDescription)
.status(ImageStatus.CREATING)
.user(user.getName())
.libraries(fetchExploratoryLibs(libraries))
.computationalLibraries(fetchComputationalLibs(libraries))
.dockerImage(userInstance.getImageName())
.exploratoryId(userInstance.getId())
.project(userInstance.getProject())
.endpoint(userInstance.getEndpoint())
.build());
exploratoryDAO.updateExploratoryStatus(new ExploratoryStatusDTO()
.withUser(user.getName())
.withProject(project)
.withExploratoryName(exploratoryName)
.withStatus(UserInstanceStatus.CREATING_IMAGE));
EndpointDTO endpointDTO = endpointService.get(userInstance.getEndpoint());
return provisioningService.post(endpointDTO.getUrl() + ExploratoryAPI.EXPLORATORY_IMAGE,
user.getAccessToken(),
requestBuilder.newExploratoryImageCreate(user, userInstance, imageName, endpointDTO, projectDTO), String.class);
}
@Override
public void finishImageCreate(Image image, String exploratoryName, String newNotebookIp) {
log.debug("Returning exploratory status with name {} to RUNNING for user {}",
exploratoryName, image.getUser());
exploratoryDAO.updateExploratoryStatus(new ExploratoryStatusDTO()
.withUser(image.getUser())
.withProject(image.getProject())
.withExploratoryName(exploratoryName)
.withStatus(UserInstanceStatus.RUNNING));
imageExploratoryDao.updateImageFields(image);
if (newNotebookIp != null) {
log.debug("Changing exploratory ip with name {} for user {} to {}", exploratoryName, image.getUser(),
newNotebookIp);
exploratoryDAO.updateExploratoryIp(image.getUser(), image.getProject(), newNotebookIp, exploratoryName);
}
}
@Override
public List<ImageInfoRecord> getNotFailedImages(String user, String dockerImage, String project, String endpoint) {
return imageExploratoryDao.getImages(user, dockerImage, project, endpoint, ImageStatus.CREATED, ImageStatus.CREATING);
}
@Override
public ImageInfoRecord getImage(String user, String name, String project, String endpoint) {
return imageExploratoryDao.getImage(user, name, project, endpoint).orElseThrow(() ->
new ResourceNotFoundException(String.format(IMAGE_NOT_FOUND_MSG, name, user)));
}
@Override
public List<ImageInfoRecord> getImagesForProject(String project) {
return imageExploratoryDao.getImagesForProject(project);
}
private Map<String, List<Library>> fetchComputationalLibs(List<Library> libraries) {
return libraries.stream()
.filter(resourceTypePredicate(ResourceType.COMPUTATIONAL))
.collect(Collectors.toMap(Library::getResourceName, Lists::newArrayList, this::merge));
}
private List<Library> merge(List<Library> oldValue, List<Library> newValue) {
oldValue.addAll(newValue);
return oldValue;
}
private List<Library> fetchExploratoryLibs(List<Library> libraries) {
return libraries.stream()
.filter(resourceTypePredicate(ResourceType.EXPLORATORY))
.collect(Collectors.toList());
}
private Predicate<Library> resourceTypePredicate(ResourceType resourceType) {
return l -> resourceType == l.getType();
}
}