20250828 cleanup (#2639)

* Cleanup

* Refactor artifact management
This commit is contained in:
Avgustin Marinov
2025-09-02 16:08:14 +03:00
committed by GitHub
parent 4f0a8893c7
commit 2a636328a0
305 changed files with 2253 additions and 4566 deletions

View File

@@ -28,73 +28,28 @@ public abstract class AbstractServerRtException extends RuntimeException {
private final SpServerError error;
private final transient Map<String, Object> info;
/**
* Parameterized constructor.
*
* @param error detail
*/
protected AbstractServerRtException(final SpServerError error) {
super(error.getMessage());
this.error = error;
this.info = null;
this(error, error.getMessage());
}
/**
* Parameterized constructor.
*
* @param message custom error message
* @param error detail
*/
protected AbstractServerRtException(final String message, final SpServerError error) {
this(message, error, (Map<String, Object>) null);
protected AbstractServerRtException(final SpServerError error, final String message) {
this(error, message, (Map<String, Object>) null);
}
/**
* Parameterized constructor.
*
* @param message custom error message
* @param error detail
*/
protected AbstractServerRtException(final String message, final SpServerError error, final Map<String, Object> info) {
super(message);
this.error = error;
this.info = info;
protected AbstractServerRtException(final SpServerError error, final String message, final Map<String, Object> info) {
this(error, message, info, null);
}
/**
* Parameterized constructor.
*
* @param message custom error message
* @param error detail
* @param cause of the exception
*/
protected AbstractServerRtException(final String message, final SpServerError error, final Throwable cause) {
super(message, cause);
this.error = error;
this.info = null;
protected AbstractServerRtException(final SpServerError error, final String message, final Throwable cause) {
this(error, message, null, cause);
}
/**
* Parameterized constructor.
*
* @param error detail
* @param cause of the exception
*/
protected AbstractServerRtException(final SpServerError error, final Throwable cause) {
super(error.getMessage(), cause);
this.error = error;
this.info = null;
this(error, error.getMessage(), null, cause);
}
/**
* Parameterized constructor.
*
* @param message custom error message
* @param error detail
* @param cause of the exception
*/
protected AbstractServerRtException(
final String message, final SpServerError error, final Throwable cause, final Map<String, Object> info) {
final SpServerError error, final String message, final Map<String, Object> info, final Throwable cause) {
super(message, cause);
this.error = error;
this.info = info;

View File

@@ -86,7 +86,7 @@ public interface TenantAware {
if (context.getAuthentication() != null) {
final Object principal = context.getAuthentication().getPrincipal();
if (context.getAuthentication().getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails) {
return tenantAwareAuthenticationDetails.getTenant();
return tenantAwareAuthenticationDetails.tenant();
} else if (principal instanceof TenantAwareUser tenantAwareUser) {
return tenantAwareUser.getTenant();
}

View File

@@ -12,31 +12,14 @@ package org.eclipse.hawkbit.tenancy;
import java.io.Serial;
import java.io.Serializable;
import lombok.Getter;
import lombok.ToString;
import org.springframework.security.authentication.AbstractAuthenticationToken;
/**
* An authentication details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the
* spring security authentication token details to transport the principal and tenant in the security context session.
*/
@Getter
@ToString
public class TenantAwareAuthenticationDetails implements Serializable {
public record TenantAwareAuthenticationDetails(String tenant, boolean controller) implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private final String tenant;
private final boolean controller;
/**
* @param tenant the current tenant
* @param controller boolean flag to indicate if this authenticated token is a controller authentication. {@code true} in case of
* authenticated controller otherwise {@code false}
*/
public TenantAwareAuthenticationDetails(final String tenant, final boolean controller) {
this.tenant = tenant;
this.controller = controller;
}
}
}

View File

@@ -19,6 +19,7 @@ import io.micrometer.core.instrument.Tag;
import io.micrometer.observation.ObservationRegistry;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.eclipse.hawkbit.tenancy.TenantAware.TenantResolver;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
@@ -59,8 +60,9 @@ public class TenantMetricsConfiguration {
public DefaultServerRequestObservationConvention serverRequestObservationConvention(final TenantResolver tenantResolver) {
return new DefaultServerRequestObservationConvention() {
@NonNull
@Override
public KeyValues getLowCardinalityKeyValues(final ServerRequestObservationContext context) {
public KeyValues getLowCardinalityKeyValues(@NonNull final ServerRequestObservationContext context) {
// Make sure that KeyValues entries are already sorted by name for better performance
return KeyValues.of(exception(context), method(context), outcome(context), status(context), tenant(), uri(context));
}

View File

@@ -7,14 +7,17 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.cache;
package org.eclipse.hawkbit.tenancy.cache;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import lombok.NonNull;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Nullable;
/**
* A {@link CacheManager} delegator which wraps the {@link CacheManager#getCache(String)} and {@link CacheManager#getCacheNames()}
@@ -22,7 +25,7 @@ import org.springframework.cache.CacheManager;
* <p/>
* Additionally, it also provides functionality to retrieve all caches overall tenants at once, for monitoring and system access.
*/
public class TenantAwareCacheManager implements TenancyCacheManager {
public class TenantAwareCacheManager implements TenantCacheManager {
private static final String TENANT_CACHE_DELIMITER = "|";
@@ -40,8 +43,9 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
this.tenantAware = tenantAware;
}
@Nullable
@Override
public Cache getCache(final String name) {
public Cache getCache(@NonNull final String name) {
final String currentTenant = tenantAware.getCurrentTenant();
if (isTenantInvalid(currentTenant)) {
return null;
@@ -50,6 +54,7 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
return delegate.getCache(buildKey(currentTenant.toUpperCase(), name));
}
@NonNull
@Override
public Collection<String> getCacheNames() {
final String currentTenant = tenantAware.getCurrentTenant();
@@ -67,7 +72,8 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
@Override
public void evictCaches(final String tenant) {
getCacheNames(tenant).forEach(cacheName -> delegate.getCache(buildKey(tenant, cacheName)).clear());
getCacheNames(tenant).forEach(
cacheName -> Optional.ofNullable(delegate.getCache(buildKey(tenant, cacheName))).ifPresent(Cache::clear));
}
/**

View File

@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.cache;
package org.eclipse.hawkbit.tenancy.cache;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
@@ -15,7 +15,7 @@ import org.springframework.cache.CacheManager;
/**
* A cache interface which handles multi tenancy.
*/
public interface TenancyCacheManager extends CacheManager {
public interface TenantCacheManager extends CacheManager {
/**
* A direct-access for retrieving the cache without including the current tenant key. This is necessary e.g. for retrieving caches not for

View File

@@ -71,7 +71,7 @@ public class ObjectCopyUtil {
final ToSetter toSetter = toSetter(toClass, setterName, fieldName, fromMethod.getReturnType());
if (toSetter == null && toGetter == null) {
// we allow toSetter to be null, but in that case the toGetter must not be null and the
// from value shall always match the to value (without setting it)
// 'from' value shall always match the to value (without setting it)
throw new IllegalStateException("Setter counterpart for " + fromMethod + " is not found in " + toClass.getName());
}
propertySetters.add(new PropertyCopyFunction(fromMethod, toSetter, toGetter));
@@ -284,50 +284,41 @@ public class ObjectCopyUtil {
private record ToSetter(BiConsumer<Object, Object> toSetter, int order) {}
@SuppressWarnings("java:S1210") // java:S1210 - return 0 only when default equals return equals, assume equal hashCodes for equal objects
private static class PropertyCopyFunction implements CopyFunction, Comparable<PropertyCopyFunction> {
private final Method fromMethod;
private final ToSetter toSetter;
private final UnaryOperator<Object> toGetter;
private PropertyCopyFunction(final Method fromMethod, final ToSetter toSetter, final UnaryOperator<Object> toGetter) {
this.fromMethod = fromMethod;
this.toGetter = toGetter;
this.toSetter = toSetter;
}
private record PropertyCopyFunction(Method fromMethod, ToSetter toSetter, UnaryOperator<Object> toGetter)
implements CopyFunction, Comparable<PropertyCopyFunction> {
public boolean apply(final Object from, final Object to, final boolean setNullValues, final UnaryOperator<Object> propertyProcessor) {
final Object value;
try {
value = fromMethod.invoke(from);
} catch (final IllegalAccessException e) {
throw new IllegalStateException("Failed to get source value", e);
} catch (final InvocationTargetException e) {
throw new IllegalStateException("Failed to get source value", e.getTargetException() == null ? e : e.getTargetException());
}
if (value == null && !setNullValues) { // if !setNullValues null means no change
return false;
}
if (toGetter != null) {
final Object currentValue = toGetter.apply(to);
if (Objects.equals(value, currentValue)) {
return false; // no change
final Object value;
try {
value = fromMethod.invoke(from);
} catch (final IllegalAccessException e) {
throw new IllegalStateException("Failed to get source value", e);
} catch (final InvocationTargetException e) {
throw new IllegalStateException("Failed to get source value", e.getTargetException() == null ? e : e.getTargetException());
}
if (value == null && !setNullValues) { // if !setNullValues null means no change
return false;
}
if (toGetter != null) {
final Object currentValue = toGetter.apply(to);
if (Objects.equals(value, currentValue)) {
return false; // no change
}
}
if (toSetter == null) {
throw new IllegalStateException(
"Setter counterpart for " + fromMethod + " is not found in " + to.getClass().getName() +
" and the 'from' value is not equal to the 'to' value");
}
toSetter.toSetter().accept(to, propertyProcessor.apply(value));
return true;
}
if (toSetter == null) {
throw new IllegalStateException(
"Setter counterpart for " + fromMethod + " is not found in " + to.getClass().getName() +
" and the 'from' value is not equal to the 'to' value");
}
toSetter.toSetter().accept(to, propertyProcessor.apply(value));
return true;
}
public int compareTo(final PropertyCopyFunction other) {
final int orderCompare = Integer.compare(this.toSetter.order(), other.toSetter.order());
return orderCompare == 0 ? Integer.compare(this.hashCode(), other.hashCode()) : orderCompare;
public int compareTo(final PropertyCopyFunction other) {
final int orderCompare = Integer.compare(this.toSetter.order(), other.toSetter.order());
return orderCompare == 0 ? Integer.compare(this.hashCode(), other.hashCode()) : orderCompare;
}
}
}
// functional interface to apply the copy operation
private interface CopyFunction {