Skip to content

Package: AbstractKapuaConfigurableResourceLimitedService

AbstractKapuaConfigurableResourceLimitedService

nameinstructionbranchcomplexitylinemethod
AbstractKapuaConfigurableResourceLimitedService(String, Domain, EntityManagerFactory, AbstractEntityCacheFactory, Class, Class)
M: 13 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
AbstractKapuaConfigurableResourceLimitedService(String, Domain, EntityManagerFactory, Class, Class)
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
allowedChildEntities(KapuaId)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
allowedChildEntities(KapuaId, KapuaId)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
allowedChildEntities(KapuaId, KapuaId, Map)
M: 56 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
checkAllowedEntities(KapuaId, String)
M: 12 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
lambda$allowedChildEntities$0(KapuaEntityFactory, KapuaId, KapuaEntityService, AccountFactory, KapuaId, AccountService, Map)
M: 84 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
validateNewConfigValuesCoherence(KapuaTocd, Map, KapuaId, KapuaId)
M: 52 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
3: *
4: * This program and the accompanying materials are made
5: * available under the terms of the Eclipse Public License 2.0
6: * which is available at https://www.eclipse.org/legal/epl-2.0/
7: *
8: * SPDX-License-Identifier: EPL-2.0
9: *
10: * Contributors:
11: * Eurotech - initial API and implementation
12: *******************************************************************************/
13: package org.eclipse.kapua.commons.configuration;
14:
15: import org.eclipse.kapua.KapuaException;
16: import org.eclipse.kapua.KapuaMaxNumberOfItemsReachedException;
17: import org.eclipse.kapua.commons.configuration.exception.ServiceConfigurationLimitExceededException;
18: import org.eclipse.kapua.commons.configuration.exception.ServiceConfigurationParentLimitExceededException;
19: import org.eclipse.kapua.commons.jpa.AbstractEntityCacheFactory;
20: import org.eclipse.kapua.commons.jpa.CacheFactory;
21: import org.eclipse.kapua.commons.jpa.EntityManagerFactory;
22: import org.eclipse.kapua.commons.security.KapuaSecurityUtils;
23: import org.eclipse.kapua.locator.KapuaLocator;
24: import org.eclipse.kapua.model.KapuaEntity;
25: import org.eclipse.kapua.model.KapuaEntityAttributes;
26: import org.eclipse.kapua.model.KapuaEntityCreator;
27: import org.eclipse.kapua.model.KapuaEntityFactory;
28: import org.eclipse.kapua.model.config.metatype.KapuaTocd;
29: import org.eclipse.kapua.model.domain.Domain;
30: import org.eclipse.kapua.model.id.KapuaId;
31: import org.eclipse.kapua.model.query.KapuaListResult;
32: import org.eclipse.kapua.model.query.KapuaQuery;
33: import org.eclipse.kapua.model.query.predicate.AttributePredicate.Operator;
34: import org.eclipse.kapua.service.KapuaEntityService;
35: import org.eclipse.kapua.service.KapuaService;
36: import org.eclipse.kapua.service.account.Account;
37: import org.eclipse.kapua.service.account.AccountFactory;
38: import org.eclipse.kapua.service.account.AccountListResult;
39: import org.eclipse.kapua.service.account.AccountQuery;
40: import org.eclipse.kapua.service.account.AccountService;
41: import org.eclipse.kapua.service.config.KapuaConfigurableService;
42:
43: import java.util.Map;
44:
45: /**
46: * Base {@code abstract} {@link KapuaConfigurableService} implementation for services that have a max number of entities allowed.
47: * <p>
48: * The usually contain properties named:
49: * <ul>
50: * <li>infiniteChildEntities</li>
51: * <li>maxNumberChildEntities</li>
52: * </ul>
53: *
54: * @param <E> The {@link KapuaEntity} type.
55: * @param <C> The {@link KapuaEntityCreator} type.
56: * @param <S> The {@link KapuaEntityService} type.
57: * @param <L> The {@link KapuaListResult} type.
58: * @param <Q> The {@link KapuaQuery} type.
59: * @param <F> The {@link KapuaEntityFactory} type.
60: * @since 1.0.0
61: */
62: public abstract class AbstractKapuaConfigurableResourceLimitedService<E extends KapuaEntity, C extends KapuaEntityCreator<E>, S extends KapuaEntityService<E, C>, L extends KapuaListResult<E>, Q extends KapuaQuery, F extends KapuaEntityFactory<E, C, Q, L>>
63: extends AbstractKapuaConfigurableService {
64:
65: private final Class<S> serviceClass;
66: private final Class<F> factoryClass;
67:
68: /**
69: * Constructor.
70: *
71: * @param pid The {@link KapuaConfigurableService} id.
72: * @param domain The {@link Domain} on which check access.
73: * @param entityManagerFactory The {@link EntityManagerFactory} that handles persistence unit
74: * @param serviceClass The {@link KapuaService} type.
75: * @param factoryClass The {@link KapuaEntityFactory} type.
76: * @deprecated Since 1.2.0. This constructor will be removed in a next release (may be)
77: */
78: @Deprecated
79: protected AbstractKapuaConfigurableResourceLimitedService(
80: String pid,
81: Domain domain,
82: EntityManagerFactory entityManagerFactory,
83: Class<S> serviceClass,
84: Class<F> factoryClass) {
85: this(pid, domain, entityManagerFactory, null, serviceClass, factoryClass);
86: }
87:
88: /**
89: * Constructor.
90: *
91: * @param pid The {@link KapuaConfigurableService} id.
92: * @param domain The {@link Domain} on which check access.
93: * @param entityManagerFactory The {@link EntityManagerFactory} that handles persistence unit
94: * @param abstractCacheFactory The {@link CacheFactory} that handles caching of the entities
95: * @param serviceClass The {@link KapuaService} type.
96: * @param factoryClass The {@link KapuaEntityFactory} type.
97: * @since 1.2.0
98: */
99: protected AbstractKapuaConfigurableResourceLimitedService(
100: String pid,
101: Domain domain,
102: EntityManagerFactory entityManagerFactory,
103: AbstractEntityCacheFactory abstractCacheFactory,
104: Class<S> serviceClass,
105: Class<F> factoryClass) {
106: super(pid, domain, entityManagerFactory, abstractCacheFactory);
107:
108: this.serviceClass = serviceClass;
109: this.factoryClass = factoryClass;
110: }
111:
112: @Override
113: protected boolean validateNewConfigValuesCoherence(KapuaTocd ocd, Map<String, Object> updatedProps, KapuaId scopeId, KapuaId parentId) throws KapuaException {
114: super.validateNewConfigValuesCoherence(ocd, updatedProps, scopeId, parentId);
115:
116: // Validate against current scope
117: long availableChildEntitiesWithNewConfig = allowedChildEntities(scopeId, null, updatedProps);
118:• if (availableChildEntitiesWithNewConfig < 0) {
119: throw new ServiceConfigurationLimitExceededException(getServicePid(), scopeId, -availableChildEntitiesWithNewConfig);
120: }
121:
122: // Validate against parent scope
123:• if (parentId != null) {
124: long availableParentEntitiesWithCurrentConfig = allowedChildEntities(parentId, scopeId);
125:• if (availableParentEntitiesWithCurrentConfig - availableChildEntitiesWithNewConfig < 0) {
126: throw new ServiceConfigurationParentLimitExceededException(getServicePid(), parentId, -(availableParentEntitiesWithCurrentConfig - availableChildEntitiesWithNewConfig));
127: }
128: }
129: return true;
130: }
131:
132: /**
133: * Checks if the given scope {@link KapuaId} can have more entities for this {@link KapuaConfigurableService}.
134: *
135: * @param scopeId The scope {@link KapuaId} to check.
136: * @param entityType The entity type of this {@link KapuaConfigurableService}
137: * @throws KapuaException
138: * @since 2.0.0
139: */
140: protected void checkAllowedEntities(KapuaId scopeId, String entityType) throws KapuaException {
141:• if (allowedChildEntities(scopeId) <= 0) {
142: throw new KapuaMaxNumberOfItemsReachedException(entityType);
143: }
144: }
145:
146: /**
147: * Gets the number of remaining allowed entity for the given scope, according to the {@link KapuaConfigurableService#getConfigValues(KapuaId)}
148: *
149: * @param scopeId The scope {@link KapuaId}.
150: * @return The number of entities remaining for the given scope
151: * @throws KapuaException
152: * @since 1.0.0
153: */
154: protected long allowedChildEntities(KapuaId scopeId) throws KapuaException {
155: return allowedChildEntities(scopeId, null, null);
156: }
157:
158: /**
159: * Gets the number of remaining allowed entity for the given scope, according to the {@link KapuaConfigurableService#getConfigValues(KapuaId)}
160: * excluding a specific scope when checking resources available.
161: * <p>
162: * The exclusion of the scope is required when updating a limit for a target account.
163: *
164: * @param scopeId The scope {@link KapuaId}.
165: * @param targetScopeId The excluded scope {@link KapuaId}.
166: * @return The number of entities remaining for the given scope
167: * @throws KapuaException
168: * @since 1.0.0
169: */
170: protected long allowedChildEntities(KapuaId scopeId, KapuaId targetScopeId) throws KapuaException {
171: return allowedChildEntities(scopeId, targetScopeId, null);
172: }
173:
174:
175: /**
176: * Gets the number of remaining allowed entity for the given scope, according to the given {@link KapuaConfigurableService}
177: * excluding a specific scope when checking resources available.
178: * <p>
179: * The exclusion of the scope is required when updating a limit for a target account.
180: *
181: * @param scopeId The scope {@link KapuaId}.
182: * @param targetScopeId The excluded scope {@link KapuaId}.
183: * @param configuration The configuration to be checked. If not provided will be read from the current service configuration
184: * @return The number of entities remaining for the given scope
185: * @throws KapuaException
186: * @since 1.0.0
187: */
188: protected long allowedChildEntities(KapuaId scopeId, KapuaId targetScopeId, Map<String, Object> configuration) throws KapuaException {
189: KapuaLocator locator = KapuaLocator.getInstance();
190: S service = locator.getService(serviceClass);
191: F factory = locator.getFactory(factoryClass);
192: AccountFactory accountFactory = locator.getFactory(AccountFactory.class);
193: AccountService accountService = locator.getService(AccountService.class);
194:
195:• Map<String, Object> finalConfig = configuration == null ? getConfigValues(scopeId, false) : configuration;
196: boolean allowInfiniteChildEntities = (boolean) finalConfig.get("infiniteChildEntities");
197:• if (!allowInfiniteChildEntities) {
198: return KapuaSecurityUtils.doPrivileged(() -> {
199: Q countQuery = factory.newQuery(scopeId);
200:
201: // Current used entities
202: long currentUsedEntities = service.count(countQuery);
203:
204: AccountQuery childAccountsQuery = accountFactory.newQuery(scopeId);
205: // Exclude the scope that is under config update
206:• if (targetScopeId != null) {
207: childAccountsQuery.setPredicate(childAccountsQuery.attributePredicate(KapuaEntityAttributes.ENTITY_ID, targetScopeId, Operator.NOT_EQUAL));
208: }
209:
210: AccountListResult childAccounts = accountService.query(childAccountsQuery);
211: // Resources assigned to children
212: long childCount = 0;
213:• for (Account childAccount : childAccounts.getItems()) {
214: Map<String, Object> childConfigValues = getConfigValues(childAccount.getId());
215: // maxNumberChildEntities can be null if such property is disabled via the
216: // isPropertyEnabled() method in the service implementation. In such case,
217: // it makes sense to treat the service as it had 0 available entities
218: boolean childAllowInfiniteChildEntities = (boolean) childConfigValues.getOrDefault("infiniteChildEntities", false);
219: Integer childMaxNumberChildEntities = (Integer) childConfigValues.getOrDefault("maxNumberChildEntities", 0);
220:• childCount += childAllowInfiniteChildEntities ? Integer.MAX_VALUE : childMaxNumberChildEntities;
221: }
222:
223: // Max allowed for this account
224: int maxChildAccounts = (int) finalConfig.get("maxNumberChildEntities");
225: return maxChildAccounts - currentUsedEntities - childCount;
226: });
227: }
228: return Integer.MAX_VALUE;
229: }
230: }