Artefact last modified is returned my DMF auth call (#600)
* Last modified is stored as part of artifact and returns accordingly by APIs. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fixed tests. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Check value > 0 Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Use created at. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Sonar issue fixed. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -179,8 +179,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
|
||||
final Long statusId = action.getId();
|
||||
|
||||
result = FileStreamingUtil.writeFileResponse(file, artifact.getFilename(),
|
||||
artifact.getLastModifiedAt() != null ? artifact.getLastModifiedAt() : artifact.getCreatedAt(),
|
||||
result = FileStreamingUtil.writeFileResponse(file, artifact.getFilename(), artifact.getCreatedAt(),
|
||||
requestResponseContextHolder.getHttpServletResponse(),
|
||||
requestResponseContextHolder.getHttpServletRequest(),
|
||||
(length, shippedSinceLastEvent, total) -> eventPublisher
|
||||
|
||||
@@ -299,7 +299,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
assertThat(target.getCreatedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY");
|
||||
assertThat(target.getCreatedAt()).isGreaterThanOrEqualTo(create);
|
||||
assertThat(target.getLastModifiedBy()).isNull();
|
||||
assertThat(target.getLastModifiedAt()).isNull();
|
||||
assertThat(target.getLastModifiedAt()).isZero();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ public class AmqpAuthenticationMessageHandler extends BaseAmqpService {
|
||||
private static DmfArtifact convertDbArtifact(final Artifact dbArtifact) {
|
||||
final DmfArtifact artifact = new DmfArtifact();
|
||||
artifact.setSize(dbArtifact.getSize());
|
||||
artifact.setLastModified(dbArtifact.getCreatedAt());
|
||||
artifact.setHashes(new DmfArtifactHash(dbArtifact.getSha1Hash(), dbArtifact.getMd5Hash()));
|
||||
return artifact;
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
|
||||
import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous;
|
||||
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
|
||||
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
|
||||
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
|
||||
import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource;
|
||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||
|
||||
@@ -380,6 +380,8 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
||||
final DmfDownloadResponse convertedMessage = verifyResult(returnMessage, HttpStatus.OK, null);
|
||||
assertThat(convertedMessage.getDownloadUrl()).isNotNull();
|
||||
assertThat(convertedMessage.getArtifact()).isNotNull();
|
||||
assertThat(convertedMessage.getArtifact().getLastModified())
|
||||
.isEqualTo(artifactManagement.findFirstBySHA1(artifact.getSha1Hash()).get().getCreatedAt());
|
||||
assertThat(convertedMessage.getArtifact().getHashes().getSha1()).isEqualTo(artifact.getSha1Hash());
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* JSON representation of artifact.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@@ -32,7 +29,10 @@ public class DmfArtifact {
|
||||
private DmfArtifactHash hashes;
|
||||
|
||||
@JsonProperty
|
||||
private Long size;
|
||||
private long size;
|
||||
|
||||
@JsonProperty
|
||||
private long lastModified;
|
||||
|
||||
@JsonProperty
|
||||
private Map<String, String> urls;
|
||||
@@ -45,6 +45,14 @@ public class DmfArtifact {
|
||||
return Collections.unmodifiableMap(urls);
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public void setLastModified(final long lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public void setUrls(final Map<String, String> urls) {
|
||||
this.urls = urls;
|
||||
}
|
||||
@@ -65,11 +73,11 @@ public class DmfArtifact {
|
||||
this.hashes = hashes;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(final Long size) {
|
||||
public void setSize(final long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.rest.util.FileStreamingUtil;
|
||||
import org.eclipse.hawkbit.rest.util.HttpUtil;
|
||||
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -76,8 +74,7 @@ public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi
|
||||
return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
return FileStreamingUtil.writeFileResponse(file, artifact.getFilename(),
|
||||
artifact.getLastModifiedAt() != null ? artifact.getLastModifiedAt() : artifact.getCreatedAt(),
|
||||
return FileStreamingUtil.writeFileResponse(file, artifact.getFilename(), artifact.getCreatedAt(),
|
||||
requestResponseContextHolder.getHttpServletResponse(), request, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class MgmtDownloadResource implements MgmtDownloadRestApi {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
return FileStreamingUtil.writeFileResponse(artifact, downloadId, null,
|
||||
return FileStreamingUtil.writeFileResponse(artifact, downloadId, 0L,
|
||||
requestResponseContextHolder.getHttpServletResponse(),
|
||||
requestResponseContextHolder.getHttpServletRequest(), null);
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ final class MgmtRestModelMapper {
|
||||
static void mapBaseToBase(final MgmtBaseEntity response, final TenantAwareBaseEntity base) {
|
||||
response.setCreatedBy(base.getCreatedBy());
|
||||
response.setLastModifiedBy(base.getLastModifiedBy());
|
||||
if (base.getCreatedAt() != null) {
|
||||
if (base.getCreatedAt() > 0) {
|
||||
response.setCreatedAt(base.getCreatedAt());
|
||||
}
|
||||
if (base.getLastModifiedAt() != null) {
|
||||
if (base.getLastModifiedAt() > 0) {
|
||||
response.setLastModifiedAt(base.getLastModifiedAt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ public class MgmtDownloadResourceTest extends AbstractManagementApiIntegrationTe
|
||||
@Autowired
|
||||
private DownloadIdCache downloadIdCache;
|
||||
|
||||
private final String downloadIdSha1 = "downloadIdSha1";
|
||||
private static final String DOWNLOAD_ID_SHA1 = "downloadIdSha1";
|
||||
|
||||
private final String downloadIdNotAvailable = "downloadIdNotAvailable";
|
||||
private static final String DOWNLOAD_ID_NOT_AVAILABLE = "downloadIdNotAvailable";
|
||||
|
||||
@Before
|
||||
public void setupCache() {
|
||||
@@ -45,7 +45,7 @@ public class MgmtDownloadResourceTest extends AbstractManagementApiIntegrationTe
|
||||
final SoftwareModule softwareModule = distributionSet.getModules().stream().findAny().get();
|
||||
final Artifact artifact = testdataFactory.createArtifacts(softwareModule.getId()).stream().findAny().get();
|
||||
|
||||
downloadIdCache.put(downloadIdSha1, new DownloadArtifactCache(DownloadType.BY_SHA1, artifact.getSha1Hash()));
|
||||
downloadIdCache.put(DOWNLOAD_ID_SHA1, new DownloadArtifactCache(DownloadType.BY_SHA1, artifact.getSha1Hash()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,7 +54,7 @@ public class MgmtDownloadResourceTest extends AbstractManagementApiIntegrationTe
|
||||
mvc.perform(get(
|
||||
MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE
|
||||
+ MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING,
|
||||
tenantAware.getCurrentTenant(), downloadIdNotAvailable)).andDo(MockMvcResultPrinter.print())
|
||||
tenantAware.getCurrentTenant(), DOWNLOAD_ID_NOT_AVAILABLE)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
}
|
||||
@@ -65,14 +65,14 @@ public class MgmtDownloadResourceTest extends AbstractManagementApiIntegrationTe
|
||||
mvc.perform(get(
|
||||
MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE
|
||||
+ MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING,
|
||||
tenantAware.getCurrentTenant(), downloadIdSha1)).andDo(MockMvcResultPrinter.print())
|
||||
tenantAware.getCurrentTenant(), DOWNLOAD_ID_SHA1)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// because cache is empty
|
||||
mvc.perform(get(
|
||||
MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE
|
||||
+ MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING,
|
||||
tenantAware.getCurrentTenant(), downloadIdSha1)).andDo(MockMvcResultPrinter.print())
|
||||
tenantAware.getCurrentTenant(), DOWNLOAD_ID_SHA1)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
||||
.andExpect(jsonPath("content.[0].id", equalTo(status.getId().intValue())))
|
||||
.andExpect(jsonPath("content.[0].type", equalTo("finished")))
|
||||
.andExpect(jsonPath("content.[0].messages", hasSize(1)))
|
||||
.andExpect(jsonPath("content.[0].reportedAt", equalTo(status.getCreatedAt().longValue())))
|
||||
.andExpect(jsonPath("content.[0].reportedAt", equalTo(status.getCreatedAt())))
|
||||
.andExpect(jsonPath("content.[1].type", equalTo("canceling")));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public interface BaseEntity extends Serializable, Identifiable<Long> {
|
||||
* @return time in {@link TimeUnit#MILLISECONDS} when the {@link BaseEntity}
|
||||
* was created.
|
||||
*/
|
||||
Long getCreatedAt();
|
||||
long getCreatedAt();
|
||||
|
||||
/**
|
||||
* @return user that created the {@link BaseEntity}.
|
||||
@@ -38,7 +38,7 @@ public interface BaseEntity extends Serializable, Identifiable<Long> {
|
||||
* @return time in {@link TimeUnit#MILLISECONDS} when the {@link BaseEntity}
|
||||
* was last time changed.
|
||||
*/
|
||||
Long getLastModifiedAt();
|
||||
long getLastModifiedAt();
|
||||
|
||||
/**
|
||||
* @return user that updated the {@link BaseEntity} last.
|
||||
|
||||
@@ -44,8 +44,8 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
|
||||
private String createdBy;
|
||||
private String lastModifiedBy;
|
||||
private Long createdAt;
|
||||
private Long lastModifiedAt;
|
||||
private long createdAt;
|
||||
private long lastModifiedAt;
|
||||
|
||||
@Version
|
||||
@Column(name = "optlock_revision")
|
||||
@@ -61,7 +61,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(name = "created_at", insertable = true, updatable = false)
|
||||
public Long getCreatedAt() {
|
||||
public long getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(name = "last_modified_at", insertable = true, updatable = true)
|
||||
public Long getLastModifiedAt() {
|
||||
public long getLastModifiedAt() {
|
||||
return lastModifiedAt;
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
}
|
||||
|
||||
@CreatedDate
|
||||
public void setCreatedAt(final Long createdAt) {
|
||||
public void setCreatedAt(final long createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
@LastModifiedDate
|
||||
public void setLastModifiedAt(final Long lastModifiedAt) {
|
||||
public void setLastModifiedAt(final long lastModifiedAt) {
|
||||
|
||||
if (isController()) {
|
||||
return;
|
||||
|
||||
@@ -458,7 +458,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.as("TargetUpdateStatus IN_SYNC")
|
||||
.allMatch(target -> TargetUpdateStatus.IN_SYNC.equals(target.getUpdateStatus()))
|
||||
.as("InstallationDate equal to LastModifiedAt")
|
||||
.allMatch(target -> target.getLastModifiedAt().equals(target.getInstallationDate()));
|
||||
.allMatch(target -> target.getLastModifiedAt() == target.getInstallationDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -119,7 +119,7 @@ public final class FileStreamingUtil {
|
||||
* if streaming fails
|
||||
*/
|
||||
public static ResponseEntity<InputStream> writeFileResponse(final AbstractDbArtifact artifact,
|
||||
final String filename, final Long lastModified, final HttpServletResponse response,
|
||||
final String filename, final long lastModified, final HttpServletResponse response,
|
||||
final HttpServletRequest request, final FileStreamingProgressListener progressListener) {
|
||||
|
||||
ResponseEntity<InputStream> result;
|
||||
@@ -131,7 +131,7 @@ public final class FileStreamingUtil {
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + filename);
|
||||
response.setHeader(HttpHeaders.ETAG, etag);
|
||||
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
if (lastModified != null) {
|
||||
if (lastModified > 0) {
|
||||
response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public final class FileStreamingUtil {
|
||||
|
||||
// Validate and process Range and If-Range headers.
|
||||
final String range = request.getHeader("Range");
|
||||
if (lastModified != null && range != null) {
|
||||
if (lastModified > 0 && range != null) {
|
||||
LOG.debug("range header for filename ({}) is: {}", filename, range);
|
||||
|
||||
// Range header matches"bytes=n-n,n-n,n-n..."
|
||||
|
||||
Reference in New Issue
Block a user