Added support for cdn download url for mgmt API and tests

Signed-off-by: Shruthi Manavalli Ramanna <shruthimanavalli.ramanna@bosch-si.com>
This commit is contained in:
Shruthi Manavalli Ramanna
2023-06-02 19:09:31 +02:00
parent 43b54b4c36
commit 0759fd80b0
12 changed files with 115 additions and 16 deletions

View File

@@ -16,6 +16,10 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.api.ApiType;
import org.eclipse.hawkbit.api.ArtifactUrl;
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
import org.eclipse.hawkbit.api.URLPlaceholder;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifactHash;
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
@@ -25,12 +29,14 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtSoftwareModuleRestApi;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtSoftwareModuleTypeRestApi;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.rest.data.ResponseList;
import org.springframework.hateoas.Link;
/**
* A mapper which maps repository model to RESTful model representation and
@@ -143,7 +149,7 @@ public final class MgmtSoftwareModuleMapper {
MgmtRestModelMapper.mapBaseToBase(artifactRest, artifact);
artifactRest.add(linkTo(methodOn(MgmtSoftwareModuleRestApi.class)
.getArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withSelfRel().expand());
.getArtifact(artifact.getSoftwareModule().getId(), artifact.getId(), null)).withSelfRel().expand());
return artifactRest;
}
@@ -155,6 +161,17 @@ public final class MgmtSoftwareModuleMapper {
.expand());
}
static void addLinks(final Artifact artifact, final MgmtArtifact response,
final ArtifactUrlHandler artifactUrlHandler, final SystemManagement systemManagement) {
List<ArtifactUrl> urls = artifactUrlHandler.getUrls(
new URLPlaceholder(systemManagement.getTenantMetadata().getTenant(),
systemManagement.getTenantMetadata().getId(), null, null,
new URLPlaceholder.SoftwareData(artifact.getSoftwareModule().getId(), artifact.getFilename(),
artifact.getId(), artifact.getSha1Hash())), ApiType.MGMT, null);
response.add(Link.of(urls.get(0).getRef()).withRel("cdn-download").expand());
}
static List<MgmtArtifact> artifactsToResponse(final Collection<Artifact> artifacts) {
if (artifacts == null) {
return Collections.emptyList();

View File

@@ -15,6 +15,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
@@ -29,6 +30,7 @@ import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
@@ -68,13 +70,21 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
private final SoftwareModuleTypeManagement softwareModuleTypeManagement;
private final ArtifactUrlHandler artifactUrlHandler;
private final SystemManagement systemManagement;
private final EntityFactory entityFactory;
MgmtSoftwareModuleResource(final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareModuleManagement,
final SoftwareModuleTypeManagement softwareModuleTypeManagement, final EntityFactory entityFactory) {
final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final ArtifactUrlHandler artifactUrlHandler, final SystemManagement systemManagement,
final EntityFactory entityFactory) {
this.artifactManagement = artifactManagement;
this.softwareModuleManagement = softwareModuleManagement;
this.softwareModuleTypeManagement = softwareModuleTypeManagement;
this.artifactUrlHandler = artifactUrlHandler;
this.systemManagement = systemManagement;
this.entityFactory = entityFactory;
}
@@ -125,15 +135,21 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
// subroutine
@SuppressWarnings("squid:S3655")
public ResponseEntity<MgmtArtifact> getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId) {
@PathVariable("artifactId") final Long artifactId,
@RequestParam(value = MgmtRestConstants.ARTIFACT_DOWNLOAD_URL_TYPE, required = false) final String artifactDownloadUrlType) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
final MgmtArtifact reponse = MgmtSoftwareModuleMapper.toResponse(module.getArtifact(artifactId).get());
final MgmtArtifact response = MgmtSoftwareModuleMapper.toResponse(module.getArtifact(artifactId).get());
if (!module.isDeleted()) {
MgmtSoftwareModuleMapper.addLinks(module.getArtifact(artifactId).get(), reponse);
if(artifactDownloadUrlType == null || artifactDownloadUrlType == "default") {
MgmtSoftwareModuleMapper.addLinks(module.getArtifact(artifactId).get(), response);
} else {
MgmtSoftwareModuleMapper.addLinks(module.getArtifact(artifactId).get(), response, artifactUrlHandler,
systemManagement);
}
}
return ResponseEntity.ok(reponse);
return ResponseEntity.ok(response);
}
@Override

View File

@@ -592,6 +592,37 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
"http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artifact.getId())));
}
@Test
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and cdn download links.")
void getArtifactWithCdnDownloadUrl() throws Exception {
// prepare data for test
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final int artifactSize = 5 * 1024;
final byte random[] = randomBytes(artifactSize);
final Artifact artifact = artifactManagement.create(
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
// perform test
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}?downloadurltype=cdn", sm.getId(), artifact.getId()).accept(
MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue())))
.andExpect(jsonPath("$.size", equalTo(random.length)))
.andExpect(jsonPath("$.hashes.md5", equalTo(artifact.getMd5Hash())))
.andExpect(jsonPath("$.hashes.sha1", equalTo(artifact.getSha1Hash())))
.andExpect(jsonPath("$.hashes.sha256", equalTo(artifact.getSha256Hash())))
.andExpect(jsonPath("$.providedFilename", equalTo("file1")))
.andExpect(jsonPath("$._links.cdn-download.href",
equalTo("http://localhost:8080/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/"
+ artifact.getFilename())))
.andExpect(jsonPath("$._links.self.href", equalTo(
"http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artifact.getId())));
}
@Test
@Description("Verifies the listing of an artifact that belongs to a soft deleted software module.")
void getArtifactSoftDeleted() throws Exception {