Skip to content

Commit

Permalink
SystemManagement getTenantMetadata - fetch details, added method getT…
Browse files Browse the repository at this point in the history
…enantMetadataWithoutDetails (#2194)

Signed-off-by: Avgustin Marinov <[email protected]>
  • Loading branch information
avgustinmm authored Jan 10, 2025
1 parent 0e4efe0 commit b294798
Show file tree
Hide file tree
Showing 19 changed files with 117 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.eclipse.hawkbit.rest.json.model.ResponseList;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.hateoas.Link;
Expand Down Expand Up @@ -179,10 +180,12 @@ private static DdiArtifact createArtifact(
file.setFilename(artifact.getFilename());
file.setSize(artifact.getSize());

final TenantMetaData tenantMetadata = systemManagement.getTenantMetadataWithoutDetails();
artifactUrlHandler
.getUrls(new URLPlaceholder(systemManagement.getTenantMetadata().getTenant(),
systemManagement.getTenantMetadata().getId(), target.getControllerId(), target.getId(),
new SoftwareData(artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getId(),
.getUrls(new URLPlaceholder(
tenantMetadata.getTenant(), tenantMetadata.getId(), target.getControllerId(), target.getId(),
new SoftwareData(
artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getId(),
artifact.getSha1Hash())),
ApiType.DDI, request.getURI())
.forEach(entry -> file.add(Link.of(entry.getRef()).withRel(entry.getRel()).expand()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,12 +585,13 @@ private List<DmfArtifact> convertArtifacts(final Target target, final List<Artif
private DmfArtifact convertArtifact(final Target target, final Artifact localArtifact) {
final DmfArtifact artifact = new DmfArtifact();

final TenantMetaData metaData = systemManagement.getTenantMetadata();
final TenantMetaData tenantMetadata = systemManagement.getTenantMetadataWithoutDetails();
artifact.setUrls(artifactUrlHandler
.getUrls(new URLPlaceholder(metaData.getTenant(),
metaData.getId(), target.getControllerId(), target.getId(),
new SoftwareData(localArtifact.getSoftwareModule().getId(), localArtifact.getFilename(),
localArtifact.getId(), localArtifact.getSha1Hash())),
.getUrls(new URLPlaceholder(
tenantMetadata.getTenant(), tenantMetadata.getId(), target.getControllerId(), target.getId(),
new SoftwareData(
localArtifact.getSoftwareModule().getId(), localArtifact.getFilename(), localArtifact.getId(),
localArtifact.getSha1Hash())),
ApiType.DMF)
.stream()
.collect(Collectors.toMap(ArtifactUrl::getProtocol, ArtifactUrl::getRef)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public void beforeEach() throws Exception {
when(tenantMetaData.getTenant()).thenReturn(TENANT);

when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData);
when(systemManagement.getTenantMetadataWithoutDetails()).thenReturn(tenantMetaData);

amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ public ResponseEntity<MgmtDistributionSet> getDistributionSet(final Long distrib
public ResponseEntity<List<MgmtDistributionSet>> createDistributionSets(final List<MgmtDistributionSetRequestBodyPost> sets) {
log.debug("creating {} distribution sets", sets.size());
// set default Ds type if ds type is null
final String defaultDsKey = systemSecurityContext
.runAsSystem(systemManagement.getTenantMetadata().getDefaultDsType()::getKey);
final String defaultDsKey = systemSecurityContext.runAsSystem(systemManagement.getTenantMetadata().getDefaultDsType()::getKey);
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey));

//check if there is already deleted DS Type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ public ResponseEntity<List<MgmtSystemTenantConfigurationValue>> updateTenantConf
}

//Try update TenantMetadata first
final Serializable defaultDsTypeValueUpdate = configurationValueMap.remove(
MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY);
final Serializable defaultDsTypeValueUpdate = configurationValueMap.remove(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY);
Long oldDefaultDsType = null;
MgmtSystemTenantConfigurationValue updatedDefaultDsType = null;
if (defaultDsTypeValueUpdate != null) {
Expand Down Expand Up @@ -150,14 +149,14 @@ private static boolean isDefaultDistributionSetTypeKey(String keyName) {
return MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY.equals(keyName);
}

private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(String keyName) {
private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(final String keyName) {
//Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response
final MgmtSystemTenantConfigurationValue response;
if (isDefaultDistributionSetTypeKey(keyName)) {
response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId());
} else {
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName,
tenantConfigurationManagement.getConfigurationValue(keyName));
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(
keyName, tenantConfigurationManagement.getConfigurationValue(keyName));
}
return response;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,5 +361,4 @@ private void assertBatchConfigurationFails(Object newRolloutApprovalEnabled, Obj
private Long getActualDefaultDsType() {
return systemManagement.getTenantMetadata().getDefaultDsType().getId();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ SecurityFilterChain filterChainREST(
(request, response, chain) -> {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
systemSecurityContext.runAsSystem(systemManagement::getTenantMetadata);
systemSecurityContext.runAsSystem(systemManagement::getTenantMetadataWithoutDetails);
}
chain.doFilter(request, response);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ public interface SystemManagement {
+ SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadata();

/**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()})
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadataWithoutDetails();

/**
* Returns {@link TenantMetaData} of given and current tenant. Creates for
* new tenants also two {@link SoftwareModuleType} (os and app) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,97 +12,56 @@
import java.util.Set;

/**
* A {@link DistributionSetType} is an abstract definition for
* {@link DistributionSet} that defines what {@link SoftwareModule}s can be
* added (optional) to {@link DistributionSet} of that type or have to added
* (mandatory) in order to be considered complete. Only complete DS can be
* assigned to a {@link Target}.
* A {@link DistributionSetType} is an abstract definition for {@link DistributionSet} that defines what {@link SoftwareModule}s can be
* added (optional) to {@link DistributionSet} of that type or have to added (mandatory) in order to be considered complete. Only complete DS
* can be assigned to a {@link Target}.
*/
public interface DistributionSetType extends Type {

/**
* @return immutable set of {@link SoftwareModuleType}s that need to be in a
* {@link DistributionSet} of this type to be
* @return immutable set of {@link SoftwareModuleType}s that need to be in a {@link DistributionSet} of this type to be
* {@link DistributionSet#isComplete()}.
*/
Set<SoftwareModuleType> getMandatoryModuleTypes();

/**
* @return immutable set of optional {@link SoftwareModuleType}s that can be
* in a {@link DistributionSet} of this type.
* @return immutable set of optional {@link SoftwareModuleType}s that can be in a {@link DistributionSet} of this type.
*/
Set<SoftwareModuleType> getOptionalModuleTypes();

/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType}.
*
* @param softwareModuleType search for
* @return <code>true</code> if found
* @param distributionSet to check for completeness
* @return <code>true</code> if the all mandatory software module types are in the system.
*/
default boolean containsModuleType(final SoftwareModuleType softwareModuleType) {
return containsMandatoryModuleType(softwareModuleType) || containsOptionalModuleType(softwareModuleType);
}
boolean checkComplete(DistributionSet distributionSet);

/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType}.
* Checks if the given {@link SoftwareModuleType} is in this {@link DistributionSetType}.
*
* @param softwareModuleTypeId search for by {@link SoftwareModuleType#getId()}
* @param softwareModuleType search for
* @return <code>true</code> if found
*/
default boolean containsModuleType(final Long softwareModuleTypeId) {
return containsMandatoryModuleType(softwareModuleTypeId) || containsOptionalModuleType(softwareModuleTypeId);
default boolean containsModuleType(final SoftwareModuleType softwareModuleType) {
return containsMandatoryModuleType(softwareModuleType) || containsOptionalModuleType(softwareModuleType);
}

/**
* Checks if the given {@link SoftwareModuleType} is in
* {@link #getMandatoryModuleTypes()}.
* Checks if the given {@link SoftwareModuleType} is in {@link #getMandatoryModuleTypes()}.
*
* @param softwareModuleType search for
* @return <code>true</code> if found
*/
default boolean containsMandatoryModuleType(final SoftwareModuleType softwareModuleType) {
return containsMandatoryModuleType(softwareModuleType.getId());
}

/**
* Checks if the given {@link SoftwareModuleType} is in
* {@link #getMandatoryModuleTypes()}.
*
* @param softwareModuleTypeId search for by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
default boolean containsMandatoryModuleType(final Long softwareModuleTypeId) {
return getMandatoryModuleTypes().stream().anyMatch(element -> element.getId().equals(softwareModuleTypeId));
return getMandatoryModuleTypes().stream().anyMatch(element -> element.getId().equals(softwareModuleType.getId()));
}

/**
* Checks if the given {@link SoftwareModuleType} is in
* {@link #getOptionalModuleTypes()}.
* Checks if the given {@link SoftwareModuleType} is in {@link #getOptionalModuleTypes()}.
*
* @param softwareModuleType search for
* @return <code>true</code> if found
*/
default boolean containsOptionalModuleType(final SoftwareModuleType softwareModuleType) {
return containsOptionalModuleType(softwareModuleType.getId());
}

/**
* Checks if the given {@link SoftwareModuleType} is in
* {@link #getOptionalModuleTypes()}.
*
* @param softwareModuleTypeId search by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
default boolean containsOptionalModuleType(final Long softwareModuleTypeId) {
return getOptionalModuleTypes().stream().anyMatch(element -> element.getId().equals(softwareModuleTypeId));
return getOptionalModuleTypes().stream().anyMatch(element -> element.getId().equals(softwareModuleType.getId()));
}

/**
* @param distributionSet to check for completeness
* @return <code>true</code> if the all mandatory software module types are
* in the system.
*/
boolean checkComplete(DistributionSet distributionSet);
}
Original file line number Diff line number Diff line change
Expand Up @@ -623,15 +623,15 @@ public Long countAutoAssignmentsForDistributionSet(final Long id) {
return distributionSetRepository.countAutoAssignmentsForDistributionSet(id);
}

// check if shall implicitly lock a distribution set
// check if it shall implicitly lock a distribution set
boolean isImplicitLockApplicable(final DistributionSet distributionSet) {
final JpaDistributionSet jpaDistributionSet = (JpaDistributionSet) distributionSet;
if (jpaDistributionSet.isLocked()) {
// already locked
return false;
}

if (!tenantConfigHelper.getConfigValue(IMPLICIT_LOCK_ENABLED, Boolean.class)) {
if (Boolean.FALSE.equals(tenantConfigHelper.getConfigValue(IMPLICIT_LOCK_ENABLED, Boolean.class))) {
// implicit lock disabled
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,7 @@ public Page<String> findTenants(final Pageable pageable) {

@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
// Exception squid:S2229 - calling findTenants without transaction is
// intended in this case
// Exception squid:S2229 - calling findTenants without transaction is intended in this case
@SuppressWarnings("squid:S2229")
public void forEachTenant(final Consumer<String> consumer) {
Page<String> tenants;
Expand Down Expand Up @@ -207,7 +206,6 @@ public SystemUsageReportWithTenants getSystemUsageStatisticsWithTenants() {

@Override
public SystemUsageReport getSystemUsageStatistics() {

final Number count = (Number) entityManager.createNativeQuery(countSoftwareModulesQuery).getSingleResult();

long sumOfArtifacts = 0;
Expand All @@ -232,22 +230,12 @@ public SystemUsageReport getSystemUsageStatistics() {

@Override
public TenantMetaData getTenantMetadata() {
final String tenant = tenantAware.getCurrentTenant();
if (tenant == null) {
throw new IllegalStateException("Tenant not set");
}
return getTenantMetadata0(true);
}

final TenantMetaData metaData = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
if (metaData == null) {
if (repositoryProperties.isImplicitTenantCreateAllowed()) {
log.info("Tenant {} doesn't exist create metadata", tenant, new Exception("Thread dump"));
return createTenantMetadata0(tenant);
} else {
throw new EntityNotFoundException(TenantMetaData.class, tenant);
}
} else {
return metaData;
}
@Override
public TenantMetaData getTenantMetadataWithoutDetails() {
return getTenantMetadata0(false);
}

@Override
Expand All @@ -265,11 +253,9 @@ public TenantMetaData createTenantMetadata(final String tenant) {
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TenantMetaData updateTenantMetadata(final long defaultDsType) {
final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadata();

final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadataWithoutDetails();
data.setDefaultDsType(distributionSetTypeRepository.findById(defaultDsType)
.orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, defaultDsType)));

return tenantMetaDataRepository.save(data);
}

Expand All @@ -283,6 +269,28 @@ private static boolean isPostgreSql(final JpaProperties properties) {
return Database.POSTGRESQL == properties.getDatabase();
}

private TenantMetaData getTenantMetadata0(final boolean withDetails) {
final String tenant = tenantAware.getCurrentTenant();
if (tenant == null) {
throw new IllegalStateException("Tenant not set");
}

final TenantMetaData metaData =
withDetails ?
tenantMetaDataRepository.findWitDetailsByTenantIgnoreCase(tenant) :
tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
if (metaData == null) {
if (repositoryProperties.isImplicitTenantCreateAllowed()) {
log.info("Tenant {} doesn't exist create metadata", tenant, new Exception("Thread dump"));
return createTenantMetadata0(tenant);
} else {
throw new EntityNotFoundException(TenantMetaData.class, tenant);
}
} else {
return metaData;
}
}

private void usageStatsPerTenant(final SystemUsageReportWithTenants report) {
forEachTenant(tenant -> report.addTenantData(systemStatsManagement.getStatsOfTenant()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
* {@link SoftwareModuleType} elements.
*/
@NoArgsConstructor // Default constructor for JPA
@Getter
@Entity
@Table(name = "sp_ds_type_element")
public class DistributionSetTypeElement implements Serializable {
Expand All @@ -47,16 +46,22 @@ public class DistributionSetTypeElement implements Serializable {
private DistributionSetTypeElementCompositeKey key;

@MapsId("dsType")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "distribution_set_type", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_element"))
@ManyToOne(optional = false)
@JoinColumn(
name = "distribution_set_type", nullable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_element"))
private JpaDistributionSetType dsType;

@Getter
@MapsId("smType")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "software_module_type", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_smtype"))
@ManyToOne(optional = false)
@JoinColumn(
name = "software_module_type", nullable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_smtype"))
private JpaSoftwareModuleType smType;

@Setter
@Getter
@Column(name = "mandatory")
private boolean mandatory;

Expand Down
Loading

0 comments on commit b294798

Please sign in to comment.