Skip to content

Commit

Permalink
Add solution data model and endpoints (#224)
Browse files Browse the repository at this point in the history
* fix deleting file

* fix mime type when creating a file

* add solution data model and endpoints

* add solutionType to solution

---------

Co-authored-by: mbeisel <beiselmn@gmail.com>
  • Loading branch information
PhilWun and mbeisel authored May 16, 2024
1 parent 5fc30e9 commit 84ec225
Show file tree
Hide file tree
Showing 8 changed files with 570 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2024 the qc-atlas contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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 org.planqk.atlas.core.model;

import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
* Entity representing a solution.
*/
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
public class Solution extends KnowledgeArtifact {

private UUID patternId;

@OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)
@EqualsAndHashCode.Exclude
@JoinTable(
name = "SolutionFile",
joinColumns = @JoinColumn(name = "solution_id"),
inverseJoinColumns = @JoinColumn(name = "file_id")
)
private File file;

private String solutionType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2024 the qc-atlas contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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 org.planqk.atlas.core.repository;

import java.util.UUID;

import org.planqk.atlas.core.model.Solution;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.stereotype.Repository;

/**
* Repository to access {@link Solution}s available in the database.
*/
@Repository
@RepositoryRestResource(exported = false)
public interface SolutionRepository extends JpaRepository<Solution, UUID> {

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.util.UUID;

import org.planqk.atlas.core.model.File;
Expand Down Expand Up @@ -54,7 +55,14 @@ public File create(MultipartFile file) {

final File createdFile = new File();
createdFile.setName(file.getOriginalFilename());
createdFile.setMimeType(file.getContentType());

var contentType = file.getContentType();

if (contentType == null) {
contentType = URLConnection.guessContentTypeFromName(file.getOriginalFilename());
}

createdFile.setMimeType(contentType);
createdFile.setFileURL(file.getOriginalFilename());

final FileData fileData = new FileData();
Expand All @@ -80,9 +88,9 @@ public File findById(UUID fileId) {
@Transactional
public void delete(UUID id) {
final File file = findById(id);
final FileData fileData = fileDataRepository.findByFile(file);
fileRepository.deleteById(id);
final var fileData = fileDataRepository.findByFile(file);
fileDataRepository.delete(fileData);
fileRepository.delete(file);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*******************************************************************************
* Copyright (c) 2020 the qc-atlas contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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 org.planqk.atlas.core.services;

import java.util.UUID;

import org.planqk.atlas.core.model.File;
import org.planqk.atlas.core.model.Implementation;
import org.planqk.atlas.core.model.Solution;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
* Service class for operations related to interacting and modifying {@link Solution}s in the database.
*/
public interface SolutionService {

/**
* Creates a new database entry for a given {@link Solution} and save it to the database.
* <p>
* The ID of the {@link Solution} parameter should be null, since the ID will be generated by the database when
* creating the entry. The validation for this is done by the Controller layer, which will reject {@link Solution}s
* with a given ID in its create path.
*
* @param solution The {@link Solution} object describing the properties of a solution that should be saved to
* the database
* @return The {@link Solution} object that represents the saved status from the database
*/
@Transactional
Solution create(Solution solution);

/**
* Retrieve multiple {@link Solution} entries from the database.
* <p>
* The amount of entries is based on the given {@link Pageable} parameter. If the {@link Pageable} is unpaged a
* {@link Page} with all entries is queried.
* <p>
* If no search should be executed the search parameter can be left null or empty.
*
* @param pageable The page information, namely page size and page number, of the page we want to retrieve
* @return The page of queried {@link Solution} entries
*/
Page<Solution> findAll(Pageable pageable);

/**
* Find a database entry of a {@link Solution} that is already saved in the database. This search is based on the
* ID the database has given the {@link Solution} object when it was created and first saved to the database.
* <p>
* If there is no entry found in the database this method will throw a {@link java.util.NoSuchElementException}.
*
* @param solutionId The ID of the {@link Solution} we want to find
* @return The {@link Solution} with the given ID
*/
Solution findById(UUID solutionId);

/**
* Update an existing {@link Solution} database entry by saving the updated {@link Solution} object to the
* database.
* <p>
* The ID of the {@link Solution} parameter has to be set to the ID of the database entry we want to update. The
* validation for this ID to be set is done by the Controller layer, which will reject {@link Solution}s without a
* given ID in its update path. This ID will be used to query the existing {@link Solution} entry we want to
* update. If no {@link Solution} entry with the given ID is found this method will throw a {@link
* java.util.NoSuchElementException}.
*
* @param solution The {@link Solution} we want to update with its updated properties
* @return the updated {@link Solution} object that represents the updated status of the database
*/
@Transactional
Solution update(Solution solution);

/**
* Delete an existing {@link Solution} entry from the database. This deletion is based on the ID the database has
* given the {@link Solution} when it was created and first saved to the database.
* <p>
* When deleting an {@link Solution} the file referenced by the {@link Solution} will be deleted together
* with it.
* If no entry with the given ID is found this method will throw a {@link java.util.NoSuchElementException}.
*
* @param solutionId The ID of the {@link Solution} we want to delete
*/
@Transactional
void delete(UUID solutionId);

/**
* Creates a {@link File} entry in the database from a multipartfile and links it to a given {@link
* Solution}.
*
* @param solutionId The ID of the {@link Solution} we want the {@link File} to be linked.
* @param multipartFile The multipart from which we want to create a File entity and link it to the {@link
* Solution}
* @return The created and linked {@link File}
*/
File addFileToSolution(UUID solutionId, MultipartFile multipartFile);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2020-2021 the qc-atlas contributors.
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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 org.planqk.atlas.core.services;

import java.util.UUID;

import org.planqk.atlas.core.model.File;
import org.planqk.atlas.core.model.Solution;
import org.planqk.atlas.core.repository.SolutionRepository;
import org.planqk.atlas.core.util.ServiceUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@AllArgsConstructor
public class SolutionServiceImpl implements SolutionService {

private final SolutionRepository solutionRepository;

private final FileService fileService;

@Override
@Transactional
public Solution create(Solution solution) {
return solutionRepository.save(solution);
}

@Override
public Page<Solution> findAll(@NonNull Pageable pageable) {
return solutionRepository.findAll(pageable);
}

@Override
public Solution findById(@NonNull UUID solutionId) {
return ServiceUtils.findById(solutionId, Solution.class, solutionRepository);
}

@Override
@Transactional
public Solution update(@NonNull Solution solution) {
final Solution persistedAlgorithm = findById(solution.getId());
persistedAlgorithm.setPatternId(solution.getPatternId());

return solutionRepository.save(persistedAlgorithm);
}

@Override
@Transactional
public void delete(@NonNull UUID solutionId) {
final Solution algorithm = findById(solutionId);

if (algorithm.getFile() != null) {
fileService.delete(algorithm.getFile().getId());
}

solutionRepository.deleteById(solutionId);
}

@Override
public File addFileToSolution(UUID solutionId, MultipartFile multipartFile) {
final Solution solution =
ServiceUtils.findById(solutionId, Solution.class, solutionRepository);
final File file = fileService.create(multipartFile);
solution.setFile(file);
solutionRepository.save(solution);

return file;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public final class Constants {

public static final String REVISIONS = "revisions";

public static final String SOLUTIONS = "solutions";

// default Pagination params that are exposed in HATEOAS links
public static final Integer DEFAULT_PAGE_NUMBER = 0;

Expand Down Expand Up @@ -126,6 +128,8 @@ public final class Constants {

public static final String TAG_TOSCA = "tosca-application-controller";

public static final String TAG_SOLUTION = "solution";

private Constants() {
}
}
Loading

0 comments on commit 84ec225

Please sign in to comment.