Skip to content

Commit

Permalink
Custom Service Configurations availability logic
Browse files Browse the repository at this point in the history
Signed-off-by: Claudio Mezzasalma <claudio.mezzasalma@eurotech.com>
  • Loading branch information
Claudio Mezzasalma committed May 8, 2020
1 parent 3f95c1a commit dc610b6
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ protected int allowedChildEntities(KapuaId scopeId, KapuaId targetScopeId, Map<S
AccountFactory accountFactory = locator.getFactory(AccountFactory.class);
AccountService accountService = locator.getService(AccountService.class);

Map<String, Object> finalConfig = configuration == null ? getConfigValues(scopeId) : configuration;
Map<String, Object> finalConfig = configuration == null ? getConfigValues(scopeId, false) : configuration;
boolean allowInfiniteChildEntities = (boolean) finalConfig.get("infiniteChildEntities");
if (!allowInfiniteChildEntities) {
return KapuaSecurityUtils.doPrivileged(() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Collectors;

/**
* Configurable service definition abstract reference implementation.
Expand Down Expand Up @@ -105,13 +106,20 @@ private void validateConfigurations(String pid, KapuaTocd ocd, Map<String, Objec
throws KapuaException {
if (ocd != null) {

// build a map of all the attribute definitions
Map<String, KapuaTad> attrDefs = new HashMap<>();
List<KapuaTad> defs = ocd.getAD();
for (KapuaTad def : defs) {
attrDefs.put(def.getId(), def);
// Get Unavailable Properties
List<KapuaTad> unavailableProperties = ocd.getAD().stream().filter(ad -> !isAvailableProperty(ad)).collect(Collectors.toList());

if (!unavailableProperties.isEmpty()) {
// If there's any unavailable property, read current values to overwrite the proposed ones
Map<String, Object> originalValues = getConfigValues(scopeId, false);
if (originalValues != null) {
unavailableProperties.forEach(unavailableProp -> updatedProps.put(unavailableProp.getId(), originalValues.get(unavailableProp.getId())));
}
}

// build a map of all the attribute definitions
Map<String, KapuaTad> attrDefs = ocd.getAD().stream().collect(Collectors.toMap(KapuaTad::getId, ad -> ad));

// loop over the proposed property values
// and validate them against the definition
for (Entry<String, Object> property : updatedProps.entrySet()) {
Expand Down Expand Up @@ -247,38 +255,49 @@ private ServiceConfig updateConfig(ServiceConfig serviceConfig)
}

@Override
public KapuaTocd getConfigMetadata(KapuaId scopeId)
throws KapuaException {
public KapuaTocd getConfigMetadata(KapuaId scopeId) throws KapuaException {
return getConfigMetadata(scopeId, true);
}

protected KapuaTocd getConfigMetadata(KapuaId scopeId, boolean excludeUnavailable) throws KapuaException {
KapuaLocator locator = KapuaLocator.getInstance();
AuthorizationService authorizationService = locator.getService(AuthorizationService.class);
PermissionFactory permissionFactory = locator.getFactory(PermissionFactory.class);

authorizationService.checkPermission(permissionFactory.newPermission(domain, Actions.read, scopeId));

String cacheKey = pid + "#" + scopeId.toCompactId() + "#" + excludeUnavailable;

try {
KapuaTmetadata metadata = KAPUA_TMETADATA_LOCAL_CACHE.get(pid);
KapuaTmetadata metadata = KAPUA_TMETADATA_LOCAL_CACHE.get(cacheKey);
if (metadata == null) {
metadata = readMetadata(pid);
if (metadata != null) {
KAPUA_TMETADATA_LOCAL_CACHE.put(pid, metadata);
KAPUA_TMETADATA_LOCAL_CACHE.put(cacheKey, metadata);
}
}
if (metadata != null && metadata.getOCD() != null && !metadata.getOCD().isEmpty()) {
for (KapuaTocd ocd : metadata.getOCD()) {
if (ocd.getId() != null && ocd.getId().equals(pid)) {
if (ocd.getId() != null && ocd.getId().equals(pid) && isAvailableService()) {
ocd.getAD().removeIf(ad -> excludeUnavailable && !isAvailableProperty(ad));
return ocd;
}
}
}
return null;
} catch (KapuaConfigurationException e) {
throw e;
} catch (Exception e) {
throw KapuaException.internalError(e);
}
}

@Override
public Map<String, Object> getConfigValues(KapuaId scopeId)
throws KapuaException {
public Map<String, Object> getConfigValues(KapuaId scopeId) throws KapuaException {
return getConfigValues(scopeId, true);
}

protected Map<String, Object> getConfigValues(KapuaId scopeId, boolean excludeUnavailable) throws KapuaException {
KapuaLocator locator = KapuaLocator.getInstance();
AuthorizationService authorizationService = locator.getService(AuthorizationService.class);
PermissionFactory permissionFactory = locator.getFactory(PermissionFactory.class);
Expand All @@ -294,15 +313,15 @@ public Map<String, Object> getConfigValues(KapuaId scopeId)
query.setPredicate(predicate);

ServiceConfigListResult result = entityManagerSession.doAction(EntityManagerContainer.<ServiceConfigListResult>create().onResultHandler(em -> ServiceDAO.query(em, ServiceConfig.class, ServiceConfigImpl.class, new ServiceConfigListResultImpl(), query))
.onBeforeHandler(() -> (ServiceConfigListResult) PRIVATE_ENTITY_CACHE.getList(scopeId, pid))
.onAfterHandler((entity) -> PRIVATE_ENTITY_CACHE.putList(scopeId, pid, entity)));
.onBeforeHandler(() -> (ServiceConfigListResult) PRIVATE_ENTITY_CACHE.getList(scopeId, pid))
.onAfterHandler(entity -> PRIVATE_ENTITY_CACHE.putList(scopeId, pid, entity)));

Properties properties = null;
if (result != null && !result.isEmpty()) {
properties = result.getFirstItem().getConfigurations();
}

KapuaTocd ocd = getConfigMetadata(scopeId);
KapuaTocd ocd = getConfigMetadata(scopeId, excludeUnavailable);
return ocd == null ? null : toValues(ocd, properties);
}

Expand All @@ -314,7 +333,7 @@ public void setConfigValues(KapuaId scopeId, KapuaId parentId, Map<String, Objec
PermissionFactory permissionFactory = locator.getFactory(PermissionFactory.class);
authorizationService.checkPermission(permissionFactory.newPermission(domain, Actions.write, scopeId));

KapuaTocd ocd = getConfigMetadata(scopeId);
KapuaTocd ocd = getConfigMetadata(scopeId, false);
validateConfigurations(pid, ocd, values, scopeId, parentId);

ServiceConfigQueryImpl query = new ServiceConfigQueryImpl(scopeId);
Expand Down Expand Up @@ -343,4 +362,13 @@ public void setConfigValues(KapuaId scopeId, KapuaId parentId, Map<String, Objec
updateConfig(serviceConfig);
}
}

protected boolean isAvailableService() {
return true;
}

protected boolean isAvailableProperty(KapuaTad ad) {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,9 @@ public enum KapuaConfigurationErrorCodes implements KapuaErrorCode {
/**
* Parent limit exceeded in config
*/
PARENT_LIMIT_EXCEEDED_IN_CONFIG
PARENT_LIMIT_EXCEEDED_IN_CONFIG,
/**
* The service is not available
*/
SERVICE_UNAVAILABLE
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void setId(String id) {
}

@Override
public void setIcon(List<? extends KapuaTicon> icon) {
public void setIcon(List<KapuaTicon> icon) {
// No OP implementation
}

Expand All @@ -64,7 +64,7 @@ public void setAny(List<Object> any) {
}

@Override
public void setAD(List<? extends KapuaTad> icon) {
public void setAD(List<KapuaTad> icon) {
// No OP implementation
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
*/
public class TocdImpl implements KapuaTocd {

protected List<TadImpl> ad;
protected List<TiconImpl> icon;
protected List<KapuaTad> ad;
protected List<KapuaTicon> icon;
protected List<Object> any;
protected String name;
protected String description;
Expand Down Expand Up @@ -85,17 +85,12 @@ public List<KapuaTad> getAD() {
if (ad == null) {
ad = new ArrayList<>();
}
return new ArrayList<>(this.ad);
return this.ad;
}

@Override
public void setAD(List<? extends KapuaTad> ad) {
if (this.ad == null) {
this.ad = new ArrayList<>();
}
for (KapuaTad adInList : ad) {
this.ad.add((TadImpl) adInList);
}
public void setAD(List<KapuaTad> ad) {
this.ad = ad;
}

/**
Expand All @@ -108,7 +103,7 @@ public void addAD(KapuaTad ad) {
this.ad = new ArrayList<>();
}

this.ad.add((TadImpl) ad);
this.ad.add(ad);
}

/**
Expand Down Expand Up @@ -136,17 +131,12 @@ public List<KapuaTicon> getIcon() {
if (icon == null) {
icon = new ArrayList<>();
}
return new ArrayList<>(this.icon);
return this.icon;
}

@Override
public void setIcon(List<? extends KapuaTicon> icon) {
if (this.icon == null) {
this.icon = new ArrayList<>();
}
for (KapuaTicon iconInList : icon) {
this.icon.add((TiconImpl) iconInList);
}
public void setIcon(List<KapuaTicon> icon) {
this.icon = icon;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ ILLEGAL_ARGUMENT=An illegal value was provided for the argument {0}. {1}
OPERATION_NOT_ALLOWED=Operation not allowed: {0}
ATTRIBUTE_INVALID=Configuration attribute invalid: {0}
REQUIRED_ATTRIBUTE_MISSING=Required configuration attribute missing: {0}
SERVICE_UNAVAILABLE=The requested service is not available for configuration. {0}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ UNABLE_TO_PARSE_CRON_EXPRESSION=Unable to parse cron expression. {0}
ENTITY_ALREADY_EXIST_IN_ANOTHER_ACCOUNT={0} already exists in another account.
EXTERNAL_ID_ALREADY_EXIST_IN_ANOTHER_ACCOUNT=An entity with the same external id {0} already exists in another account.
SELF_LIMIT_EXCEEDED_IN_CONFIG=Value too small, please remove some items or increase value.
SERVICE_UNAVAILABLE=The requested service is not available for configuration. {0}
ENTITY_NOT_FOUND=The entity of type {0} with id/name {1} was not found.
DEVICE_NOT_FOUND=The selected devices were not found. Please refresh device list.
BUNDLE_START_ERROR=Bundle could not be started. Please check the device log for errors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public interface KapuaTocd {
@XmlElement(name = "AD", namespace = "http://www.osgi.org/xmlns/metatype/v1.2.0", required = true)
List<KapuaTad> getAD();

void setAD(List<? extends KapuaTad> icon);
void setAD(List<KapuaTad> icon);

/**
* Gets the value of the icon property.
Expand All @@ -90,7 +90,7 @@ public interface KapuaTocd {
@XmlElement(name = "Icon", namespace = "http://www.osgi.org/xmlns/metatype/v1.2.0")
List<KapuaTicon> getIcon();

void setIcon(List<? extends KapuaTicon> icon);
void setIcon(List<KapuaTicon> icon);

/**
* Gets the value of the any property.
Expand Down

0 comments on commit dc610b6

Please sign in to comment.