Abstract RepositoryManagement test (#2631)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -239,11 +239,10 @@ public interface ControllerManagement {
|
||||
*
|
||||
* @param actionId to the handle status for
|
||||
* @param message for the status
|
||||
* @return the update action in case the status has been changed to {@link Status#RETRIEVED}
|
||||
* @throws EntityNotFoundException if action with given ID does not exist
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||
Action registerRetrieved(long actionId, String message);
|
||||
void registerRetrieved(long actionId, String message);
|
||||
|
||||
/**
|
||||
* Updates attributes of the controller according to the given {@link UpdateMode}.
|
||||
@@ -260,8 +259,7 @@ public interface ControllerManagement {
|
||||
Target updateControllerAttributes(@NotEmpty String controllerId, @NotNull Map<String, String> attributes, UpdateMode mode);
|
||||
|
||||
/**
|
||||
* Finds {@link Target} based on given controller ID returns found Target without details, i.e.
|
||||
* NO {@link Target#getTags()} and {@link Target#getActions()} possible.
|
||||
* Finds {@link Target} based on given controller ID returns found Target without details
|
||||
*
|
||||
* @param controllerId to look for.
|
||||
* @return {@link Target} or {@code null} if it does not exist
|
||||
@@ -271,9 +269,7 @@ public interface ControllerManagement {
|
||||
Optional<Target> findByControllerId(@NotEmpty String controllerId);
|
||||
|
||||
/**
|
||||
* Finds {@link Target} based on given ID returns found Target without details, i.e.
|
||||
* NO {@link Target#getTags()} and {@link Target#getActions()}
|
||||
* possible.
|
||||
* Finds {@link Target} based on given ID returns found Target without details
|
||||
*
|
||||
* @param targetId to look for.
|
||||
* @return {@link Target} or {@code null} if it does not exist
|
||||
|
||||
@@ -242,16 +242,6 @@ public interface DeploymentManagement extends PermissionSupport {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
Page<ActionStatus> findActionStatusByAction(long actionId, @NotNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Counts all the {@link ActionStatus} entries of the given {@link Action}.
|
||||
*
|
||||
* @param actionId to be filtered on
|
||||
* @return count of {@link ActionStatus} entries
|
||||
* @throws EntityNotFoundException if action with given ID does not exist
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
long countActionStatusByAction(long actionId);
|
||||
|
||||
/**
|
||||
* Retrieves all messages for an {@link ActionStatus}.<p/>
|
||||
* No entity based access control applied.
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
@@ -20,17 +17,9 @@ import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
import org.eclipse.hawkbit.repository.model.Tag;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
/**
|
||||
* Management service for {@link DistributionSetTag}s.
|
||||
|
||||
@@ -88,11 +88,9 @@ public final class MaintenanceScheduleHelper {
|
||||
if (allNotEmpty(cronSchedule, duration, timezone)) {
|
||||
validateCronSchedule(cronSchedule);
|
||||
validateDuration(duration);
|
||||
// check if there is a window currently active or available in
|
||||
// future.
|
||||
if (!getNextMaintenanceWindow(cronSchedule, duration, timezone).isPresent()) {
|
||||
throw new InvalidMaintenanceScheduleException(
|
||||
"No valid maintenance window available after current time");
|
||||
// check if there is a window currently active or available in the future.
|
||||
if (getNextMaintenanceWindow(cronSchedule, duration, timezone).isEmpty()) {
|
||||
throw new InvalidMaintenanceScheduleException("No valid maintenance window available after current time");
|
||||
}
|
||||
} else if (atLeastOneNotEmpty(cronSchedule, duration, timezone)) {
|
||||
throw new InvalidMaintenanceScheduleException("All of schedule, duration and timezone should either be null or non empty.");
|
||||
|
||||
@@ -18,11 +18,9 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link PageRequest} which is offset based by means
|
||||
* the offset is given and not the page number as in the original
|
||||
* {@link PageRequest} implementation where the offset is generated. Due that
|
||||
* the REST-API is working with {@code offset} and {@code limit} parameter we
|
||||
* need an offset based page request.
|
||||
* An implementation of the {@link PageRequest} which is offset based by means the offset is given and not the page number as in the original
|
||||
* {@link PageRequest} implementation where the offset is generated. Due to the REST-API is working with {@code offset} and {@code limit}
|
||||
* parameter we need an offset based page request.
|
||||
*/
|
||||
@Getter
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -20,8 +20,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
public interface QuotaManagement {
|
||||
|
||||
/**
|
||||
* @return maximum number of {@link ActionStatus} entries that the
|
||||
* controller can report for an {@link Action}.
|
||||
* @return maximum number of {@link ActionStatus} entries that the controller can report for an {@link Action}.
|
||||
*/
|
||||
int getMaxStatusEntriesPerAction();
|
||||
|
||||
@@ -31,15 +30,12 @@ public interface QuotaManagement {
|
||||
int getMaxAttributeEntriesPerTarget();
|
||||
|
||||
/**
|
||||
* @return maximum number of allowed {@link RolloutGroup}s per
|
||||
* {@link Rollout}.
|
||||
* @return maximum number of allowed {@link RolloutGroup}s per {@link Rollout}.
|
||||
*/
|
||||
int getMaxRolloutGroupsPerRollout();
|
||||
|
||||
/**
|
||||
* @return maximum number of
|
||||
* {@link ControllerManagement#getActionHistoryMessages(Long, int)}
|
||||
* for an individual {@link ActionStatus}.
|
||||
* @return maximum number of action (history) messages per actions status.
|
||||
*/
|
||||
int getMaxMessagesPerActionStatus();
|
||||
|
||||
@@ -49,7 +45,7 @@ public interface QuotaManagement {
|
||||
int getMaxMetaDataEntriesPerSoftwareModule();
|
||||
|
||||
/**
|
||||
* @return maximum number of meta data entries per distribution set
|
||||
* @return maximum number of metadata entries per distribution set
|
||||
*/
|
||||
int getMaxMetaDataEntriesPerDistributionSet();
|
||||
|
||||
@@ -80,14 +76,12 @@ public interface QuotaManagement {
|
||||
int getMaxTargetsPerRolloutGroup();
|
||||
|
||||
/**
|
||||
* @return the maximum number of target distribution set assignments
|
||||
* resulting from a manual assignment
|
||||
* @return the maximum number of target distribution set assignments resulting from a manual assignment
|
||||
*/
|
||||
int getMaxTargetDistributionSetAssignmentsPerManualAssignment();
|
||||
|
||||
/**
|
||||
* @return the maximum number of targets for an automatic distribution set
|
||||
* assignment
|
||||
* @return the maximum number of targets for an automatic distribution set assignment
|
||||
*/
|
||||
int getMaxTargetsPerAutoAssignment();
|
||||
|
||||
@@ -110,5 +104,4 @@ public interface QuotaManagement {
|
||||
* @return the maximum number of distribution set types per target type
|
||||
*/
|
||||
int getMaxDistributionSetTypesPerTargetType();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Collection of regular expression characters to check strings
|
||||
*/
|
||||
public class RegexCharacterCollection {
|
||||
|
||||
private final EnumSet<RegexChar> characters;
|
||||
private final Pattern findAnyCharacter;
|
||||
|
||||
public RegexCharacterCollection(final RegexChar... characters) {
|
||||
this.characters = EnumSet.copyOf(Arrays.asList(characters));
|
||||
this.findAnyCharacter = getPatternFindAnyCharacter();
|
||||
}
|
||||
|
||||
public static boolean stringContainsCharacter(final String stringToCheck,
|
||||
final RegexCharacterCollection regexCharacterCollection) {
|
||||
return regexCharacterCollection.findAnyCharacter.matcher(stringToCheck).matches();
|
||||
}
|
||||
|
||||
private Pattern getPatternFindAnyCharacter() {
|
||||
final String regexCharacters = characters.stream().map(RegexChar::getRegExp)
|
||||
.collect(Collectors.joining());
|
||||
final String regularExpression = String.format(".*[%s]+.*", regexCharacters);
|
||||
return Pattern.compile(regularExpression);
|
||||
}
|
||||
|
||||
public enum RegexChar {
|
||||
WHITESPACE("\\s", "character.whitespace"), DIGITS("0-9", "character.digits"), QUOTATION_MARKS("'\"",
|
||||
"character.quotationMarks"), SLASHES("\\/\\\\", "character.slashes"), GREATER_THAN(
|
||||
">"), LESS_THAN("<"), EQUALS_SYMBOL("="), EXCLAMATION_MARK("!"), QUESTION_MARK("?"), COLON(":");
|
||||
|
||||
private final String regExp;
|
||||
private final String l18nReferenceDescription;
|
||||
|
||||
RegexChar(final String character) {
|
||||
this(character, null);
|
||||
}
|
||||
|
||||
RegexChar(final String regExp, final String l18nReferenceDescription) {
|
||||
this.regExp = regExp;
|
||||
this.l18nReferenceDescription = l18nReferenceDescription;
|
||||
}
|
||||
|
||||
public String getRegExp() {
|
||||
return regExp;
|
||||
}
|
||||
|
||||
public Optional<String> getL18nReferenceDescription() {
|
||||
return Optional.ofNullable(l18nReferenceDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.repository;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
|
||||
@@ -23,15 +22,12 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
public final class RepositoryConstants {
|
||||
|
||||
/**
|
||||
* Prefix that the server puts in front of
|
||||
* {@link ActionStatus#getMessages()} if the message is generated by the
|
||||
* server.
|
||||
* Prefix that the server puts in front of action status messages if the message is generated by the server.
|
||||
*/
|
||||
public static final String SERVER_MESSAGE_PREFIX = "Update Server: ";
|
||||
|
||||
/**
|
||||
* Number of {@link DistributionSetType}s that are generated as part of
|
||||
* default tenant setup.
|
||||
* Number of {@link DistributionSetType}s that are generated as part of default tenant setup.
|
||||
*/
|
||||
public static final int DEFAULT_DS_TYPES_IN_TENANT = 3;
|
||||
|
||||
@@ -41,8 +37,7 @@ public final class RepositoryConstants {
|
||||
public static final int MAX_ACTION_COUNT = 100;
|
||||
|
||||
/**
|
||||
* Maximum number of messages that can be retrieved by a controller for an
|
||||
* {@link Action}.
|
||||
* Maximum number of messages that can be retrieved by a controller for an {@link Action}.
|
||||
*/
|
||||
public static final int MAX_ACTION_HISTORY_MSG_COUNT = 100;
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
@@ -22,32 +23,25 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||
public interface RolloutExecutor {
|
||||
|
||||
/**
|
||||
* This execution should only be triggered by the system as a background job and
|
||||
* not available via API.
|
||||
*
|
||||
* This execution should only be triggered by the system as a background job and not available via API.
|
||||
* <p/>
|
||||
* Process rollout based on its current {@link Rollout#getStatus()}.
|
||||
*
|
||||
* For {@link RolloutStatus#CREATING} that means creating the
|
||||
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
|
||||
* {@link RolloutStatus#READY}.
|
||||
*
|
||||
* For {@link RolloutStatus#READY} that means switching to
|
||||
* {@link RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is set and
|
||||
* time of calling this method is beyond this point in time. This auto start
|
||||
* mechanism is optional. Call {@link #start(Long)} otherwise.
|
||||
*
|
||||
* For {@link RolloutStatus#STARTING} that means starting the first
|
||||
* {@link RolloutGroup}s in line and when finished switch to
|
||||
* <p/>
|
||||
* For {@link RolloutStatus#CREATING} that means creating the {@link org.eclipse.hawkbit.repository.model.RolloutGroup}s
|
||||
* with {@link Target}s and when finished switch to {@link RolloutStatus#READY}.
|
||||
* <p/>
|
||||
* For {@link RolloutStatus#READY} that means switching to {@link RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is set and
|
||||
* time of calling this method is beyond this point in time. This auto start mechanism is optional.
|
||||
* Call {@link RolloutManagement#start(long)} otherwise.
|
||||
* <p/>
|
||||
* For {@link RolloutStatus#STARTING} that means starting the first {@link RolloutGroup}s in line and when finished switch to
|
||||
* {@link RolloutStatus#RUNNING}.
|
||||
*
|
||||
* For {@link RolloutStatus#RUNNING} that means checking to activate further
|
||||
* groups based on the defined thresholds. Switched to
|
||||
* <p/>
|
||||
* For {@link RolloutStatus#RUNNING} that means checking to activate further groups based on the defined thresholds. Switched to
|
||||
* {@link RolloutStatus#FINISHED} is all groups are finished.
|
||||
*
|
||||
* For {@link RolloutStatus#DELETING} that means either soft delete in case
|
||||
* rollout was already {@link RolloutStatus#RUNNING} which results in status
|
||||
* change {@link RolloutStatus#DELETED} or hard delete from the persistence
|
||||
* otherwise.
|
||||
* <p/>
|
||||
* For {@link RolloutStatus#DELETING} that means either soft delete in case rollout was already {@link RolloutStatus#RUNNING}
|
||||
* which results in status change {@link RolloutStatus#DELETED} or hard delete from the persistence otherwise.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
void execute(Rollout rollout);
|
||||
|
||||
@@ -95,15 +95,6 @@ public interface RolloutGroupManagement extends PermissionSupport {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
Page<RolloutGroup> findByRollout(long rolloutId, @NotNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Retrieves a page of {@link RolloutGroup}s filtered by a given {@link Rollout}.
|
||||
*
|
||||
* @param rolloutId the ID of the rollout to filter the {@link RolloutGroup}s
|
||||
* @return a page of found {@link RolloutGroup}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
long countByRollout(long rolloutId);
|
||||
|
||||
/**
|
||||
* Get targets of specified rollout group.
|
||||
*
|
||||
|
||||
@@ -24,27 +24,22 @@ public interface RolloutHandler {
|
||||
|
||||
/**
|
||||
* Process rollout based on its current {@link Rollout#getStatus()}.
|
||||
*
|
||||
* For {@link Rollout.RolloutStatus#CREATING} that means creating the
|
||||
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
|
||||
* <p/>
|
||||
* For {@link Rollout.RolloutStatus#CREATING} that means creating the {@link RolloutGroup}s with {@link Target}s and when finished switch to
|
||||
* {@link Rollout.RolloutStatus#READY}.
|
||||
*
|
||||
* For {@link Rollout.RolloutStatus#READY} that means switching to
|
||||
* {@link Rollout.RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is
|
||||
* set and time of calling this method is beyond this point in time. This auto
|
||||
* <p/>
|
||||
* For {@link Rollout.RolloutStatus#READY} that means switching to {@link Rollout.RolloutStatus#STARTING} if the
|
||||
* {@link Rollout#getStartAt()} is set and time of calling this method is beyond this point in time. This auto
|
||||
* start mechanism is optional. Call {@link RolloutManagement#start(long)} otherwise.
|
||||
*
|
||||
* For {@link Rollout.RolloutStatus#STARTING} that means starting the first
|
||||
* {@link RolloutGroup}s in line and when finished switch to
|
||||
* <p/>
|
||||
* For {@link Rollout.RolloutStatus#STARTING} that means starting the first {@link RolloutGroup}s in line and when finished switch to
|
||||
* {@link Rollout.RolloutStatus#RUNNING}.
|
||||
*
|
||||
* For {@link Rollout.RolloutStatus#RUNNING} that means checking to activate
|
||||
* further groups based on the defined thresholds. Switched to
|
||||
* <p/>
|
||||
* For {@link Rollout.RolloutStatus#RUNNING} that means checking to activate further groups based on the defined thresholds. Switched to
|
||||
* {@link Rollout.RolloutStatus#FINISHED} is all groups are finished.
|
||||
*
|
||||
* For {@link Rollout.RolloutStatus#DELETING} that means either soft delete in
|
||||
* case rollout was already {@link Rollout.RolloutStatus#RUNNING} which results
|
||||
* in status change {@link Rollout.RolloutStatus#DELETED} or hard delete from
|
||||
* <p/>
|
||||
* For {@link Rollout.RolloutStatus#DELETING} that means either soft delete in case rollout was already
|
||||
* {@link Rollout.RolloutStatus#RUNNING} which results in status change {@link Rollout.RolloutStatus#DELETED} or hard delete from
|
||||
* the persistence otherwise.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
|
||||
@@ -86,25 +86,19 @@ public interface RolloutManagement extends PermissionSupport {
|
||||
long countByDistributionSetIdAndRolloutIsStoppable(long setId);
|
||||
|
||||
/**
|
||||
* Persists a new rollout entity. The filter within the
|
||||
* {@link Rollout#getTargetFilterQuery()} is used to retrieve the targets which
|
||||
* are effected by this rollout to create. The amount of groups will be defined
|
||||
* as equally sized.
|
||||
*
|
||||
* The rollout is not started. Only the preparation of the rollout is done,
|
||||
* creating and persisting all the necessary groups. The Rollout and the groups
|
||||
* are persisted in {@link RolloutStatus#CREATING} and
|
||||
* {@link RolloutGroupStatus#CREATING}.
|
||||
*
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all
|
||||
* targets have been assigned to the groups, the rollout status is changed to
|
||||
* {@link RolloutStatus#READY} so it can be started with .
|
||||
* Persists a new rollout entity. The filter within the {@link Rollout#getTargetFilterQuery()} is used to retrieve the targets which
|
||||
* are effected by this rollout to create. The amount of groups will be defined as equally sized.
|
||||
* <p/>
|
||||
* The rollout is not started. Only the preparation of the rollout is done, creating and persisting all the necessary groups. The Rollout
|
||||
* and the groups are persisted in {@link RolloutStatus#CREATING} and {@link RolloutGroupStatus#CREATING}.
|
||||
* <p/>
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all targets have been assigned to the groups, the rollout status
|
||||
* is changed to {@link RolloutStatus#READY} so it can be started with .
|
||||
*
|
||||
* @param create the rollout entity to create
|
||||
* @param amountGroup the amount of groups to split the rollout into
|
||||
* @param confirmationRequired if a confirmation is required by the device group(s) of the rollout
|
||||
* @param conditions the rolloutgroup conditions and actions which should be applied
|
||||
* for each {@link RolloutGroup}
|
||||
* @param conditions the rolloutgroup conditions and actions which should be applied for each {@link RolloutGroup}
|
||||
* @param dynamicRolloutGroupTemplate the template for dynamic rollout groups
|
||||
* @return the persisted rollout.
|
||||
* @throws EntityNotFoundException if given {@link DistributionSet} does not exist
|
||||
@@ -118,61 +112,45 @@ public interface RolloutManagement extends PermissionSupport {
|
||||
@NotNull RolloutGroupConditions conditions, DynamicRolloutGroupTemplate dynamicRolloutGroupTemplate);
|
||||
|
||||
/**
|
||||
* Persists a new rollout entity. The filter within the
|
||||
* {@link Rollout#getTargetFilterQuery()} is used to retrieve the targets which
|
||||
* are effected by this rollout to create. The amount of groups will be defined
|
||||
* as equally sized.
|
||||
*
|
||||
* The rollout is not started. Only the preparation of the rollout is done,
|
||||
* creating and persisting all the necessary groups. The Rollout and the groups
|
||||
* are persisted in {@link RolloutStatus#CREATING} and
|
||||
* {@link RolloutGroupStatus#CREATING}.
|
||||
*
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all
|
||||
* targets have been assigned to the groups, the rollout status is changed to
|
||||
* {@link RolloutStatus#READY} so it can be started with .
|
||||
* Persists a new rollout entity. The filter within the {@link Rollout#getTargetFilterQuery()} is used to retrieve the targets which
|
||||
* are effected by this rollout to create. The amount of groups will be defined as equally sized.
|
||||
* <p/>
|
||||
* The rollout is not started. Only the preparation of the rollout is done, creating and persisting all the necessary groups. The Rollout
|
||||
* and the groups are persisted in {@link RolloutStatus#CREATING} and {@link RolloutGroupStatus#CREATING}.
|
||||
* <p/>
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all targets have been assigned to the groups, the rollout status is
|
||||
* changed to {@link RolloutStatus#READY} so it can be started with .
|
||||
*
|
||||
* @param create the rollout entity to create
|
||||
* @param amountGroup the amount of groups to split the rollout into
|
||||
* @param confirmationRequired if a confirmation is required by the device group(s) of the rollout
|
||||
* @param conditions the rolloutgroup conditions and actions which should be applied
|
||||
* for each {@link RolloutGroup}
|
||||
* @param conditions the rolloutgroup conditions and actions which should be applied for each {@link RolloutGroup}
|
||||
* @return the persisted rollout.
|
||||
* @throws EntityNotFoundException if given {@link DistributionSet} does not exist
|
||||
* @throws ConstraintViolationException if rollout or group parameters are invalid.
|
||||
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
|
||||
* exceeded.
|
||||
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is exceeded.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
|
||||
Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired,
|
||||
@NotNull RolloutGroupConditions conditions);
|
||||
Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired, @NotNull RolloutGroupConditions conditions);
|
||||
|
||||
/**
|
||||
* Persists a new rollout entity. The filter within the
|
||||
* {@link Rollout#getTargetFilterQuery()} is used to filter the targets which
|
||||
* are affected by this rollout. The given groups will be used to create the
|
||||
* groups.
|
||||
*
|
||||
* The rollout is not started. Only the preparation of the rollout is done,
|
||||
* creating and persisting all the necessary groups. The Rollout and the groups
|
||||
* are persisted in {@link RolloutStatus#CREATING} and
|
||||
* {@link RolloutGroupStatus#CREATING}.
|
||||
*
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all
|
||||
* targets have been assigned to the groups, the rollout status is changed to
|
||||
* {@link RolloutStatus#READY} so it can be started with
|
||||
* {@link #start(long)}.
|
||||
* Persists a new rollout entity. The filter within the {@link Rollout#getTargetFilterQuery()} is used to filter the targets which
|
||||
* are affected by this rollout. The given groups will be used to create the groups.
|
||||
* <p/>
|
||||
* The rollout is not started. Only the preparation of the rollout is done, creating and persisting all the necessary groups. The Rollout
|
||||
* and the groups are persisted in {@link RolloutStatus#CREATING} and {@link RolloutGroupStatus#CREATING}.
|
||||
* <p/>
|
||||
* The RolloutScheduler will start to assign targets to the groups. Once all targets have been assigned to the groups, the rollout status is
|
||||
* changed to {@link RolloutStatus#READY} so it can be started with {@link #start(long)}.
|
||||
*
|
||||
* @param rollout the rollout entity to create
|
||||
* @param groups optional definition of groups
|
||||
* @param conditions the rollout group conditions and actions which should be applied
|
||||
* for each {@link RolloutGroup} if not defined by the RolloutGroup
|
||||
* itself
|
||||
* @param conditions the rollout group conditions and actions which should be applied for each {@link RolloutGroup} if not defined by the
|
||||
* RolloutGroup itself
|
||||
* @return the persisted rollout.
|
||||
* @throws EntityNotFoundException if given {@link DistributionSet} does not exist
|
||||
* @throws ConstraintViolationException if rollout or group parameters are invalid
|
||||
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
|
||||
* exceeded.
|
||||
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is exceeded.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
|
||||
Rollout create(@Valid @NotNull Create rollout, @NotNull @Valid List<GroupCreate> groups, RolloutGroupConditions conditions);
|
||||
@@ -192,8 +170,7 @@ public interface RolloutManagement extends PermissionSupport {
|
||||
*
|
||||
* @param deleted flag if deleted rollouts should be included
|
||||
* @param pageable the page request to sort and limit the result
|
||||
* @return a list of rollouts with details of targets count for different
|
||||
* statuses
|
||||
* @return a list of rollouts with details of targets count for different statuses
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
Page<Rollout> findAllWithDetailedStatus(boolean deleted, @NotNull Pageable pageable);
|
||||
@@ -218,7 +195,7 @@ public interface RolloutManagement extends PermissionSupport {
|
||||
* @param rsql search text which matches name or description of rollout
|
||||
* @param deleted flag if deleted rollouts should be included
|
||||
* @param pageable the page request to sort and limit the result
|
||||
* @return the founded rollout or {@code null} if rollout with given ID does not exists
|
||||
* @return the founded rollout or {@code null} if rollout with given ID does not exist
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
Page<Rollout> findByRsqlWithDetailedStatus(@NotEmpty String rsql, boolean deleted, @NotNull Pageable pageable);
|
||||
@@ -356,6 +333,7 @@ public interface RolloutManagement extends PermissionSupport {
|
||||
|
||||
/**
|
||||
* Stop a rollout
|
||||
*
|
||||
* @param rolloutId of the rollout to be stopped
|
||||
* @return stopped rollout
|
||||
*/
|
||||
|
||||
@@ -11,10 +11,7 @@ package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
@@ -25,8 +22,6 @@ import lombok.ToString;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
@@ -36,7 +31,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule.MetadataValue;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
/**
|
||||
@@ -90,6 +84,7 @@ public interface SoftwareModuleManagement<T extends SoftwareModule>
|
||||
@ToString(callSuper = true)
|
||||
final class Create extends UpdateCreate {
|
||||
|
||||
private SoftwareModuleType type;
|
||||
private boolean encrypted;
|
||||
}
|
||||
|
||||
@@ -123,6 +118,5 @@ public interface SoftwareModuleManagement<T extends SoftwareModule>
|
||||
@ValidString
|
||||
@Size(max = SoftwareModule.VENDOR_MAX_SIZE)
|
||||
private String vendor;
|
||||
private SoftwareModuleType type;
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,4 @@ public interface SystemManagement {
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('UPDATE_" + SpPermission.TENANT_CONFIGURATION + "')")
|
||||
TenantMetaData updateTenantMetadata(long defaultDsType);
|
||||
|
||||
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
TenantMetaData getTenantMetadata(long tenantId);
|
||||
}
|
||||
@@ -56,13 +56,12 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
|
||||
* Verifies the provided filter syntax.
|
||||
*
|
||||
* @param query to verify
|
||||
* @return <code>true</code> if syntax is valid
|
||||
* @throws RSQLParameterUnsupportedFieldException if a field in the RSQL string is used but not provided by the
|
||||
* given {@code fieldNameProvider}
|
||||
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
boolean verifyTargetFilterQuerySyntax(@NotNull String query);
|
||||
void verifyTargetFilterQuerySyntax(@NotNull String query);
|
||||
|
||||
/**
|
||||
* Counts all target filters that have a given auto assign distribution set
|
||||
|
||||
@@ -60,7 +60,6 @@ public interface TargetManagement<T extends Target>
|
||||
String HAS_READ_TARGET_AND_READ_ROLLOUT = HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.ROLLOUT + "')";
|
||||
String HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET = HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')";
|
||||
|
||||
String DETAILS_BASE = "base";
|
||||
String DETAILS_AUTO_CONFIRMATION_STATUS = "autoConfirmationStatus";
|
||||
String DETAILS_TAGS = "tags";
|
||||
|
||||
@@ -111,11 +110,6 @@ public interface TargetManagement<T extends Target>
|
||||
@PreAuthorize(HAS_READ_REPOSITORY)
|
||||
Target getWithDetails(@NotEmpty String controllerId, String detailsKey);
|
||||
|
||||
@PreAuthorize(HAS_READ_REPOSITORY)
|
||||
default Target getWithDetails(@NotEmpty String controllerId) {
|
||||
return getWithDetails(controllerId, DETAILS_BASE);
|
||||
}
|
||||
|
||||
@PreAuthorize(HAS_READ_REPOSITORY)
|
||||
default Target getWithAutoConfigurationStatus(@NotEmpty String controllerId) {
|
||||
return getWithDetails(controllerId, DETAILS_AUTO_CONFIRMATION_STATUS);
|
||||
|
||||
@@ -59,8 +59,7 @@ public interface TenantConfigurationManagement extends PermissionSupport {
|
||||
<T extends Serializable> Map<String, TenantConfigurationValue<T>> addOrUpdateConfiguration(Map<String, T> configurations);
|
||||
|
||||
/**
|
||||
* Deletes a specific configuration for the current tenant. Does nothing in
|
||||
* case there is no tenant specific configuration value.
|
||||
* Deletes a specific configuration for the current tenant. Does nothing in case there is no tenant specific configuration value.
|
||||
*
|
||||
* @param configurationKey the configuration key to be deleted
|
||||
*/
|
||||
@@ -68,59 +67,46 @@ public interface TenantConfigurationManagement extends PermissionSupport {
|
||||
void deleteConfiguration(String configurationKey);
|
||||
|
||||
/**
|
||||
* Retrieves a configuration value from the e.g. tenant overwritten
|
||||
* configuration values or in case the tenant does not a have a specific
|
||||
* Retrieves a configuration value from the e.g. tenant overwritten configuration values or in case the tenant does not a have a specific
|
||||
* configuration the global default value hold in the {@link Environment}.
|
||||
*
|
||||
* @param configurationKeyName the key of the configuration
|
||||
* @return the converted configuration value either from the tenant specific
|
||||
* configuration stored or from the fall back default values or
|
||||
* {@code null} in case key has not been configured and not default
|
||||
* value exists
|
||||
* @return the converted configuration value either from the tenant specific configuration stored or from the fallback default values or
|
||||
* {@code null} in case key has not been configured and not default value exists
|
||||
* @throws TenantConfigurationValidatorException if the {@code propertyType} and the value in general does not
|
||||
* match the expected type and format defined by the Key
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName);
|
||||
|
||||
/**
|
||||
* Retrieves a configuration value from the e.g. tenant overwritten
|
||||
* configuration values or in case the tenant does not a have a specific
|
||||
* Retrieves a configuration value from the e.g. tenant overwritten configuration values or in case the tenant does not a have a specific
|
||||
* configuration the global default value hold in the {@link Environment}.
|
||||
*
|
||||
* @param <T> the type of the configuration value
|
||||
* @param configurationKeyName the key of the configuration
|
||||
* @param propertyType the type of the configuration value, e.g. {@code String.class}
|
||||
* , {@code Integer.class}, etc
|
||||
* @return the converted configuration value either from the tenant specific
|
||||
* configuration stored or from the fallback default values or
|
||||
* {@code null} in case key has not been configured and not default
|
||||
* value exists
|
||||
* @param propertyType the type of the configuration value, e.g. {@code String.class}, {@code Integer.class}, etc
|
||||
* @return the converted configuration value either from the tenant specific configuration stored or from the fallback default values or
|
||||
* {@code null} in case key has not been configured and not default value exists
|
||||
* @throws TenantConfigurationValidatorException if the {@code propertyType} and the value in general does not
|
||||
* match the expected type and format defined by the Key
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName,
|
||||
Class<T> propertyType);
|
||||
|
||||
/**
|
||||
* returns the global configuration property either defined in the property
|
||||
* file or an default value otherwise.
|
||||
* returns the global configuration property either defined in the property file or a default value otherwise.
|
||||
*
|
||||
* @param <T> the type of the configuration value
|
||||
* @param configurationKeyName the key of the configuration
|
||||
* @param propertyType the type of the configuration value, e.g. {@code String.class}
|
||||
* , {@code Integer.class}, etc
|
||||
* @param propertyType the type of the configuration value, e.g. {@code String.class}, {@code Integer.class}, etc
|
||||
* @return the global configured value
|
||||
* @throws TenantConfigurationValidatorException if the {@code propertyType} and the value in the property
|
||||
* file or the default value does not match the expected type
|
||||
* and format defined by the Key
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given
|
||||
* {@code propertyType}
|
||||
* @throws TenantConfigurationValidatorException if the {@code propertyType} and the value in the property file or the default value
|
||||
* does not match the expected type and format defined by the Key
|
||||
* @throws ConversionFailedException if the property cannot be converted to the given {@code propertyType}
|
||||
*/
|
||||
@PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
|
||||
<T> T getGlobalConfigurationValue(String configurationKeyName, Class<T> propertyType);
|
||||
|
||||
@@ -25,7 +25,8 @@ public interface TenantStatsManagement {
|
||||
*
|
||||
* @return collected statistics
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('" + SpRole.TENANT_ADMIN + "')" + " or " +
|
||||
@PreAuthorize(
|
||||
"hasAuthority('" + SpRole.TENANT_ADMIN + "')" + " or " +
|
||||
SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + " or " +
|
||||
SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||
TenantUsage getStatsOfTenant();
|
||||
|
||||
@@ -13,8 +13,7 @@ import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Enumerates the supported update modes. Each mode represents an attribute
|
||||
* update strategy.
|
||||
* Enumerates the supported update modes. Each mode represents an attribute update strategy.
|
||||
*
|
||||
* @see ControllerManagement
|
||||
*/
|
||||
@@ -34,9 +33,4 @@ public enum UpdateMode {
|
||||
* Removal update strategy
|
||||
*/
|
||||
REMOVE;
|
||||
|
||||
public static Optional<UpdateMode> valueOfIgnoreCase(final String name) {
|
||||
return Arrays.stream(values()).filter(mode -> mode.name().equalsIgnoreCase(name)).findAny();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class ValidStringValidator implements ConstraintValidator<ValidString, St
|
||||
try {
|
||||
return cleaner.isValid(stringToDocument(value));
|
||||
} catch (final Exception ex) {
|
||||
log.error(String.format("There was an exception during bean field value (%s) validation", value), ex);
|
||||
log.error("There was an exception during bean field value ({}) validation", value, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Holds distribution set filter parameters.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public final class DistributionSetFilter {
|
||||
|
||||
private final Boolean isDeleted;
|
||||
private final Boolean isComplete;
|
||||
private final Boolean isValid;
|
||||
private final Long typeId;
|
||||
private final String searchText;
|
||||
private final Boolean selectDSWithNoTag;
|
||||
private final Collection<String> tagNames;
|
||||
}
|
||||
@@ -14,9 +14,8 @@ import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The poll time object which holds all the necessary information around the
|
||||
* target poll time, e.g. the last poll time, the next poll time and the overdue
|
||||
* poll time.
|
||||
* The poll time object which holds all the necessary information around the target poll time, e.g. the last poll time, the next poll time and
|
||||
* the overdue poll time.
|
||||
*/
|
||||
@Data
|
||||
public class PollStatus {
|
||||
@@ -26,7 +25,8 @@ public class PollStatus {
|
||||
private final LocalDateTime overdueDate;
|
||||
private final LocalDateTime currentDate;
|
||||
|
||||
public PollStatus(final LocalDateTime lastPollDate, final LocalDateTime nextPollDate,
|
||||
public PollStatus(
|
||||
final LocalDateTime lastPollDate, final LocalDateTime nextPollDate,
|
||||
final LocalDateTime overdueDate, final LocalDateTime currentDate) {
|
||||
this.lastPollDate = lastPollDate;
|
||||
this.nextPollDate = nextPollDate;
|
||||
@@ -35,11 +35,9 @@ public class PollStatus {
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates if the target poll time is overdue and the target has not been
|
||||
* polled in the configured poll time interval.
|
||||
* Calculates if the target poll time is overdue and the target has not been polled in the configured poll time interval.
|
||||
*
|
||||
* @return {@code true} if the current time is after the poll time overdue
|
||||
* date otherwise {@code false}.
|
||||
* @return {@code true} if the current time is after the poll time overdue date otherwise {@code false}.
|
||||
*/
|
||||
public boolean isOverdue() {
|
||||
return currentDate.isAfter(overdueDate);
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.eclipse.hawkbit.repository.RegexCharacterCollection.RegexChar;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Feature: Unit Tests - Repository<br/>
|
||||
* Story: Regular expression helper
|
||||
*/
|
||||
class RegexCharTest {
|
||||
|
||||
private static final int INDEX_FIRST_PRINTABLE_ASCII_CHAR = 32;
|
||||
private static final int INDEX_LAST_PRINTABLE_ASCII_CHAR = 127;
|
||||
private static final String TEST_STRING = getPrintableAsciiCharacters();
|
||||
|
||||
/**
|
||||
* Verifies every RegexChar can be used to exclusively find the desired characters in a String.
|
||||
*/
|
||||
@Test
|
||||
void allRegexCharsOnlyFindExpectedChars() {
|
||||
for (final RegexChar character : RegexChar.values()) {
|
||||
switch (character) {
|
||||
case DIGITS:
|
||||
assertRegexCharExclusivelyFindsGivenCharacters(character, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
break;
|
||||
case WHITESPACE:
|
||||
assertRegexCharExclusivelyFindsGivenCharacters(character, " ", "\t");
|
||||
break;
|
||||
case SLASHES:
|
||||
assertRegexCharExclusivelyFindsGivenCharacters(character, "/", "\\");
|
||||
break;
|
||||
case QUOTATION_MARKS:
|
||||
assertRegexCharExclusivelyFindsGivenCharacters(character, "\"", "'");
|
||||
break;
|
||||
default:
|
||||
assertRegexCharExclusivelyFindsGivenCharacters(character, character.getRegExp());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that combinations of RegexChars can be used to find the desired characters in a String.
|
||||
*/
|
||||
@Test
|
||||
void combinedRegexCharsFindExpectedChars() {
|
||||
final RegexCharacterCollection greaterAndLessThan = new RegexCharacterCollection(RegexChar.GREATER_THAN,
|
||||
RegexChar.LESS_THAN);
|
||||
final RegexCharacterCollection equalsAndQuestionMark = new RegexCharacterCollection(RegexChar.EQUALS_SYMBOL,
|
||||
RegexChar.QUESTION_MARK);
|
||||
final RegexCharacterCollection colonAndWhitespace = new RegexCharacterCollection(RegexChar.COLON,
|
||||
RegexChar.WHITESPACE);
|
||||
|
||||
assertRegexCharsExclusivelyFindsGivenCharacters(greaterAndLessThan, "<", ">");
|
||||
assertRegexCharsExclusivelyFindsGivenCharacters(equalsAndQuestionMark, "=", "?");
|
||||
assertRegexCharsExclusivelyFindsGivenCharacters(colonAndWhitespace, ":", " ", "\t");
|
||||
}
|
||||
|
||||
private static String getPrintableAsciiCharacters() {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = INDEX_FIRST_PRINTABLE_ASCII_CHAR; i < INDEX_LAST_PRINTABLE_ASCII_CHAR; i++) {
|
||||
stringBuilder.append((char) i);
|
||||
}
|
||||
stringBuilder.append("\t");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static String insertStringIntoString(final String baseString, final String stringToInsert,
|
||||
final int position) {
|
||||
final StringBuilder stringBuilder = new StringBuilder(baseString);
|
||||
return stringBuilder.insert(position, stringToInsert).toString();
|
||||
}
|
||||
|
||||
private void assertRegexCharExclusivelyFindsGivenCharacters(final RegexChar characterToVerify,
|
||||
final String... charactersExpectedToBeFoundByRegex) {
|
||||
assertRegexCharsExclusivelyFindsGivenCharacters(new RegexCharacterCollection(characterToVerify),
|
||||
charactersExpectedToBeFoundByRegex);
|
||||
}
|
||||
|
||||
private void assertRegexCharsExclusivelyFindsGivenCharacters(final RegexCharacterCollection regexToVerify,
|
||||
final String... charactersExpectedToBeFoundByRegex) {
|
||||
String notMatchingString = TEST_STRING;
|
||||
for (final String character : charactersExpectedToBeFoundByRegex) {
|
||||
notMatchingString = notMatchingString.replace(character, "");
|
||||
}
|
||||
for (final String character : charactersExpectedToBeFoundByRegex) {
|
||||
assertThat(RegexCharacterCollection.stringContainsCharacter("", regexToVerify)).isFalse();
|
||||
assertThat(RegexCharacterCollection.stringContainsCharacter(notMatchingString, regexToVerify)).isFalse();
|
||||
assertThat(RegexCharacterCollection.stringContainsCharacter(character, regexToVerify)).isTrue();
|
||||
assertThat(RegexCharacterCollection
|
||||
.stringContainsCharacter(insertStringIntoString(notMatchingString, character, 0), regexToVerify))
|
||||
.isTrue();
|
||||
assertThat(RegexCharacterCollection.stringContainsCharacter(
|
||||
insertStringIntoString(notMatchingString, character, notMatchingString.length()), regexToVerify)).isTrue();
|
||||
assertThat(RegexCharacterCollection.stringContainsCharacter(
|
||||
insertStringIntoString(notMatchingString, character, notMatchingString.length() / 2), regexToVerify)).isTrue();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user