Fixed download progress event.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
kaizimmerm
2016-07-07 14:46:29 +02:00
parent a9204fe5eb
commit 8fb2bd4322
15 changed files with 73 additions and 127 deletions

View File

@@ -56,7 +56,7 @@ public class EventDistributorTest {
@Test @Test
public void distributeDistributedEventSendsToRedis() { public void distributeDistributedEventSendsToRedis() {
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L);
underTest.distribute(event); underTest.distribute(event);
// origin node ID should be set by distributing the event // origin node ID should be set by distributing the event
@@ -67,7 +67,7 @@ public class EventDistributorTest {
@Test @Test
public void dontDistributeDistributedEventIfSameNode() { public void dontDistributeDistributedEventIfSameNode() {
final String knownNodeId = EventDistributor.getNodeId(); final String knownNodeId = EventDistributor.getNodeId();
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L);
event.setNodeId(knownNodeId); event.setNodeId(knownNodeId);
// test // test
@@ -79,7 +79,7 @@ public class EventDistributorTest {
@Test @Test
public void handleDistributedMessageFromRedis() { public void handleDistributedMessageFromRedis() {
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L);
final String knownChannel = "someChannel"; final String knownChannel = "someChannel";
underTest.handleMessage(event, knownChannel); underTest.handleMessage(event, knownChannel);
@@ -90,7 +90,7 @@ public class EventDistributorTest {
@Test @Test
public void handleDistributedMessageFilteredIfSameNodeId() { public void handleDistributedMessageFilteredIfSameNodeId() {
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L);
final String knownChannel = "someChannel"; final String knownChannel = "someChannel";
event.setOriginNodeId(EventDistributor.getNodeId()); event.setOriginNodeId(EventDistributor.getNodeId());

View File

@@ -21,7 +21,8 @@ public class DownloadProgressEvent extends AbstractDistributedEvent {
private final Long statusId; private final Long statusId;
private final int progressPercent; private final int progressPercent;
private final long shippedBytes; private final long shippedBytesSinceLast;
private final long shippedBytesOverall;
/** /**
* Constructor. * Constructor.
@@ -29,40 +30,39 @@ public class DownloadProgressEvent extends AbstractDistributedEvent {
* @param tenant * @param tenant
* the tenant for this event * the tenant for this event
* @param statusId * @param statusId
* of {@link Action} * of {@link ActionStatus}
* @param progressPercent * @param progressPercent
* number (1-100) * number (1-100)
* @param shippedBytesSinceLast
* bytes since last event
* @param shippedBytesOverall
* on the download request
*/ */
public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent, public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent,
final long shippedBytes) { final long shippedBytesSinceLast, final long shippedBytesOverall) {
// the revision of the DownloadProgressEvent is just equal the // the revision of the DownloadProgressEvent is just equal the
// progressPercentage due the // progressPercentage due the
// percentage is going from 0 to 100. // percentage is going from 0 to 100.
super(statusId, tenant); super(statusId, tenant);
this.statusId = statusId; this.statusId = statusId;
this.progressPercent = progressPercent; this.progressPercent = progressPercent;
this.shippedBytes = shippedBytes; this.shippedBytesSinceLast = shippedBytesSinceLast;
this.shippedBytesOverall = shippedBytesOverall;
} }
/**
* @return the statusId
*/
public Long getStatusId() { public Long getStatusId() {
return statusId; return statusId;
} }
/**
* @return the progressPercent
*/
public int getProgressPercent() { public int getProgressPercent() {
return progressPercent; return progressPercent;
} }
/** public long getShippedBytesSinceLast() {
* @return the shippedBytes return shippedBytesSinceLast;
*/
public long getShippedBytes() {
return shippedBytes;
} }
public long getShippedBytesOverall() {
return shippedBytesOverall;
}
} }

View File

@@ -93,12 +93,12 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
// we set a download status only if we are aware of the // we set a download status only if we are aware of the
// targetid, i.e. authenticated and not anonymous // targetid, i.e. authenticated and not anonymous
if (targetid != null && !"anonymous".equals(targetid)) { if (targetid != null && !"anonymous".equals(targetid)) {
final Action action = checkAndReportDownloadByTarget( final ActionStatus actionStatus = checkAndReportDownloadByTarget(
requestResponseContextHolder.getHttpServletRequest(), targetid, artifact); requestResponseContextHolder.getHttpServletRequest(), targetid, artifact);
result = RestResourceConversionHelper.writeFileResponse(artifact, result = RestResourceConversionHelper.writeFileResponse(artifact,
requestResponseContextHolder.getHttpServletResponse(), requestResponseContextHolder.getHttpServletResponse(),
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement, requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
action.getId()); actionStatus.getId());
} else { } else {
result = RestResourceConversionHelper.writeFileResponse(artifact, result = RestResourceConversionHelper.writeFileResponse(artifact,
requestResponseContextHolder.getHttpServletResponse(), requestResponseContextHolder.getHttpServletResponse(),
@@ -131,7 +131,7 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid, private ActionStatus checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
final LocalArtifact artifact) { final LocalArtifact artifact) {
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, securityProperties)); IpUtil.getClientIpFromRequest(request, securityProperties));
@@ -152,8 +152,8 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
actionStatus.addMessage( actionStatus.addMessage(
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI());
} }
controllerManagement.addInformationalActionStatus(actionStatus);
return action; return controllerManagement.addInformationalActionStatus(actionStatus);
} }
} }

View File

@@ -156,8 +156,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) { if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
} else { } else {
final Action action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(), target, final ActionStatus action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(),
module); target, module);
result = RestResourceConversionHelper.writeFileResponse(artifact, result = RestResourceConversionHelper.writeFileResponse(artifact,
requestResponseContextHolder.getHttpServletResponse(), requestResponseContextHolder.getHttpServletResponse(),
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement, requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
@@ -167,7 +167,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
return result; return result;
} }
private Action checkAndLogDownload(final HttpServletRequest request, final Target target, private ActionStatus checkAndLogDownload(final HttpServletRequest request, final Target target,
final SoftwareModule module) { final SoftwareModule module) {
final Action action = controllerManagement final Action action = controllerManagement
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module); .getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module);
@@ -185,8 +185,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
statusMessage.addMessage( statusMessage.addMessage(
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI()); RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI());
} }
controllerManagement.addInformationalActionStatus(statusMessage);
return action; return controllerManagement.addInformationalActionStatus(statusMessage);
} }
private static boolean checkModule(final String fileName, final SoftwareModule module) { private static boolean checkModule(final String fileName, final SoftwareModule module) {

View File

@@ -67,6 +67,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
private volatile int downLoadProgress = 0; private volatile int downLoadProgress = 0;
private volatile long shippedBytes = 0; private volatile long shippedBytes = 0;
private volatile long shippedBytesTotal = 0;
@Autowired @Autowired
private EventBus eventBus; private EventBus eventBus;
@@ -240,7 +241,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
public void downloadArtifactThroughFileName() throws Exception { public void downloadArtifactThroughFileName() throws Exception {
downLoadProgress = 1; downLoadProgress = 1;
shippedBytes = 0; shippedBytes = 0;
tenantStatsManagement.resetTrafficStatsOfTenant(); shippedBytesTotal = 0;
eventBus.register(this); eventBus.register(this);
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
@@ -281,8 +282,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
// download complete // download complete
assertThat(downLoadProgress).isEqualTo(10); assertThat(downLoadProgress).isEqualTo(10);
assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
.isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes());
} }
@Test @Test
@@ -321,7 +321,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception { public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception {
downLoadProgress = 1; downLoadProgress = 1;
shippedBytes = 0; shippedBytes = 0;
tenantStatsManagement.resetTrafficStatsOfTenant(); shippedBytesTotal = 0;
eventBus.register(this); eventBus.register(this);
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
@@ -329,7 +329,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
// create target // create target
Target target = entityFactory.generateTarget("4712"); Target target = entityFactory.generateTarget("4712");
target = targetManagement.createTarget(target); target = targetManagement.createTarget(target);
final List<Target> targets = new ArrayList(); final List<Target> targets = new ArrayList<>();
targets.add(target); targets.add(target);
// create ds // create ds
@@ -337,7 +337,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
// create artifact // create artifact
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE); final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false); ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
// download fails as artifact is not yet assigned to target // download fails as artifact is not yet assigned to target
@@ -346,8 +346,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
assertThat(downLoadProgress).isEqualTo(1); assertThat(downLoadProgress).isEqualTo(1);
assertThat(shippedBytes).isEqualTo(0) assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(0L);
.isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes());
} }
@Test @Test
@@ -356,7 +355,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
public void downloadArtifactByNameByNamedController() throws Exception { public void downloadArtifactByNameByNamedController() throws Exception {
downLoadProgress = 1; downLoadProgress = 1;
shippedBytes = 0; shippedBytes = 0;
tenantStatsManagement.resetTrafficStatsOfTenant(); shippedBytesTotal = 0;
eventBus.register(this); eventBus.register(this);
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
@@ -404,8 +403,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
// download complete // download complete
assertThat(downLoadProgress).isEqualTo(10); assertThat(downLoadProgress).isEqualTo(10);
assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
.isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes());
} }
@Test @Test
@@ -567,6 +565,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
@Subscribe @Subscribe
public void listen(final DownloadProgressEvent event) { public void listen(final DownloadProgressEvent event) {
downLoadProgress++; downLoadProgress++;
shippedBytes += event.getShippedBytes(); shippedBytes += event.getShippedBytesSinceLast();
shippedBytesTotal = event.getShippedBytesOverall();
} }
} }

View File

@@ -25,7 +25,6 @@ public class MgmtSystemTenantServiceUsage {
private long artifacts; private long artifacts;
private long actions; private long actions;
private long overallArtifactVolumeInBytes; private long overallArtifactVolumeInBytes;
private long overallArtifactTrafficInBytes;
/** /**
* Constructor. * Constructor.
@@ -36,14 +35,6 @@ public class MgmtSystemTenantServiceUsage {
this.tenantName = tenantName; this.tenantName = tenantName;
} }
public long getOverallArtifactTrafficInBytes() {
return overallArtifactTrafficInBytes;
}
public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) {
this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes;
}
public long getTargets() { public long getTargets() {
return targets; return targets;
} }

View File

@@ -87,7 +87,6 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi
result.setArtifacts(tenant.getArtifacts()); result.setArtifacts(tenant.getArtifacts());
result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes()); result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes());
result.setTargets(tenant.getTargets()); result.setTargets(tenant.getTargets());
result.setOverallArtifactTrafficInBytes(tenant.getOverallArtifactTrafficInBytes());
return result; return result;
} }

View File

@@ -65,11 +65,14 @@ public interface ControllerManagement {
* the ID of the {@link ActionStatus} * the ID of the {@link ActionStatus}
* @param progressPercent * @param progressPercent
* the progress in percentage which must be between 0-100 * the progress in percentage which must be between 0-100
* @param shippedBytes * @param shippedBytesSinceLast
* since last event * since the last report
* @param shippedBytesOverall
* for the {@link ActionStatus}
*/ */
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
void downloadProgressPercent(long statusId, int progressPercent, long shippedBytes); void downloadProgressPercent(long statusId, int progressPercent, long shippedBytesSinceLast,
long shippedBytesOverall);
/** /**
* Simple addition of a new {@link ActionStatus} entry to the {@link Action} * Simple addition of a new {@link ActionStatus} entry to the {@link Action}
@@ -77,9 +80,11 @@ public interface ControllerManagement {
* *
* @param statusMessage * @param statusMessage
* to add to the action * to add to the action
*
* @return create {@link ActionStatus} entity
*/ */
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
void addInformationalActionStatus(@NotNull ActionStatus statusMessage); ActionStatus addInformationalActionStatus(@NotNull ActionStatus statusMessage);
/** /**
* Adds an {@link ActionStatus} entry for an update {@link Action} including * Adds an {@link ActionStatus} entry for an update {@link Action} including

View File

@@ -29,12 +29,4 @@ public interface TenantStatsManagement {
+ SpringEvalExpressions.IS_SYSTEM_CODE) + SpringEvalExpressions.IS_SYSTEM_CODE)
TenantUsage getStatsOfTenant(); TenantUsage getStatsOfTenant();
/**
* Resets {@link TenantUsage#getOverallArtifactTrafficInBytes()} to zero.
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_SYSTEM_CODE)
void resetTrafficStatsOfTenant();
} }

View File

@@ -19,7 +19,6 @@ public class TenantUsage {
private long artifacts; private long artifacts;
private long actions; private long actions;
private long overallArtifactVolumeInBytes; private long overallArtifactVolumeInBytes;
private long overallArtifactTrafficInBytes;
/** /**
* Constructor. * Constructor.
@@ -106,28 +105,12 @@ public class TenantUsage {
return this; return this;
} }
/**
* @return the overallArtifactTrafficInBytes
*/
public long getOverallArtifactTrafficInBytes() {
return overallArtifactTrafficInBytes;
}
/**
* @param overallArtifactTrafficInBytes
* the overallArtifactTrafficInBytes to set
*/
public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) {
this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + (int) (actions ^ (actions >>> 32)); result = prime * result + (int) (actions ^ (actions >>> 32));
result = prime * result + (int) (artifacts ^ (artifacts >>> 32)); result = prime * result + (int) (artifacts ^ (artifacts >>> 32));
result = prime * result + (int) (overallArtifactTrafficInBytes ^ (overallArtifactTrafficInBytes >>> 32));
result = prime * result + (int) (overallArtifactVolumeInBytes ^ (overallArtifactVolumeInBytes >>> 32)); result = prime * result + (int) (overallArtifactVolumeInBytes ^ (overallArtifactVolumeInBytes >>> 32));
result = prime * result + (int) (targets ^ (targets >>> 32)); result = prime * result + (int) (targets ^ (targets >>> 32));
result = prime * result + ((tenantName == null) ? 0 : tenantName.hashCode()); result = prime * result + ((tenantName == null) ? 0 : tenantName.hashCode());
@@ -142,7 +125,7 @@ public class TenantUsage {
if (obj == null) { if (obj == null) {
return false; return false;
} }
if (getClass() != obj.getClass()) { if (!(obj instanceof TenantUsage)) {
return false; return false;
} }
final TenantUsage other = (TenantUsage) obj; final TenantUsage other = (TenantUsage) obj;
@@ -152,9 +135,6 @@ public class TenantUsage {
if (artifacts != other.artifacts) { if (artifacts != other.artifacts) {
return false; return false;
} }
if (overallArtifactTrafficInBytes != other.overallArtifactTrafficInBytes) {
return false;
}
if (overallArtifactVolumeInBytes != other.overallArtifactVolumeInBytes) { if (overallArtifactVolumeInBytes != other.overallArtifactVolumeInBytes) {
return false; return false;
} }
@@ -174,8 +154,7 @@ public class TenantUsage {
@Override @Override
public String toString() { public String toString() {
return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
+ ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]";
+ ", overallArtifactTrafficInBytes=" + overallArtifactTrafficInBytes + "]";
} }
} }

View File

@@ -451,8 +451,8 @@ public class JpaControllerManagement implements ControllerManagement {
@Override @Override
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void addInformationalActionStatus(final ActionStatus statusMessage) { public ActionStatus addInformationalActionStatus(final ActionStatus statusMessage) {
actionStatusRepository.save((JpaActionStatus) statusMessage); return actionStatusRepository.save((JpaActionStatus) statusMessage);
} }
@Override @Override
@@ -469,8 +469,9 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { public void downloadProgressPercent(final long statusId, final int progressPercent,
cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytes); final long shippedBytesSinceLast, final long shippedBytesOverall) {
cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytesSinceLast, shippedBytesOverall);
} }
} }

View File

@@ -8,12 +8,8 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -23,8 +19,6 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import com.google.common.eventbus.Subscribe;
/** /**
* Management service for statistics of a single tenant. * Management service for statistics of a single tenant.
* *
@@ -44,8 +38,6 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
@Autowired @Autowired
private TenantAware tenantAware; private TenantAware tenantAware;
private final Map<String, AtomicLong> traffic = new ConcurrentHashMap<>();
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public TenantUsage getStatsOfTenant() { public TenantUsage getStatsOfTenant() {
@@ -64,26 +56,9 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
} }
result.setActions(actionRepository.count()); result.setActions(actionRepository.count());
if (traffic.containsKey(tenant)) {
result.setOverallArtifactTrafficInBytes(traffic.get(tenant).get());
}
return result; return result;
} }
@Override
public void resetTrafficStatsOfTenant() {
traffic.remove(tenantAware.getCurrentTenant());
}
@Subscribe
public void listen(final DownloadProgressEvent event) {
if (traffic.containsKey(event.getTenant())) {
traffic.get(event.getTenant()).addAndGet(event.getShippedBytes());
} else {
traffic.put(event.getTenant(), new AtomicLong(event.getShippedBytes()));
}
}
} }

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.jpa.cache;
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -54,12 +53,15 @@ public class CacheWriteNotify {
* the ID of the {@link ActionStatus} * the ID of the {@link ActionStatus}
* @param progressPercent * @param progressPercent
* the progress in percentage which must be between 0-100 * the progress in percentage which must be between 0-100
* @param shippedBytes * @param shippedBytesSinceLast
* since last event * since last event
* @param shippedBytesOverall
* for the download request
*/ */
public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { public void downloadProgressPercent(final long statusId, final int progressPercent,
final long shippedBytesSinceLast, final long shippedBytesOverall) {
final Cache cache = cacheManager.getCache(Action.class.getName()); final Cache cache = cacheManager.getCache(ActionStatus.class.getName());
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId), final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
CacheKeys.DOWNLOAD_PROGRESS_PERCENT); CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
if (progressPercent < DOWNLOAD_PROGRESS_MAX) { if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
@@ -71,8 +73,8 @@ public class CacheWriteNotify {
cache.evict(cacheKey); cache.evict(cacheKey);
} }
eventBus.post( eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent,
new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent, shippedBytes)); shippedBytesSinceLast, shippedBytesOverall));
} }
/** /**

View File

@@ -14,7 +14,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -61,12 +61,12 @@ public class CacheWriteNotifyTest {
final long knownStatusId = 1; final long knownStatusId = 1;
final int knownPercentage = 23; final int knownPercentage = 23;
when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock); when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock);
when(tenantAwareMock.getCurrentTenant()).thenReturn("default"); when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L); underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L, 500L);
verify(cacheManagerMock).getCache(eq(Action.class.getName())); verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName()));
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage); verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage);
verify(eventBusMock).post(any(DownloadProgressEvent.class)); verify(eventBusMock).post(any(DownloadProgressEvent.class));
} }

View File

@@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -87,7 +88,7 @@ public final class RestResourceConversionHelper {
* @param controllerManagement * @param controllerManagement
* to write progress updates to * to write progress updates to
* @param statusId * @param statusId
* of the UpdateActionStatus * of the {@link ActionStatus}
* *
* @return http code * @return http code
* *
@@ -319,7 +320,8 @@ public final class RestResourceConversionHelper {
// every 10 percent an event // every 10 percent an event
if (newPercent == 100 || newPercent > progressPercent + 10) { if (newPercent == 100 || newPercent > progressPercent + 10) {
progressPercent = newPercent; progressPercent = newPercent;
controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent); controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent,
total);
shippedSinceLastEvent = 0; shippedSinceLastEvent = 0;
} }
} }