Added auto assign distribution set to target filter query feature
Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -38,6 +38,10 @@ local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# IDEA
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describing the fields of the Target model which can be used in the REST API
|
||||
* e.g. for sorting etc.
|
||||
*
|
||||
*/
|
||||
public enum TargetFilterQueryFields implements FieldNameProvider {
|
||||
|
||||
/**
|
||||
* The id field.
|
||||
*/
|
||||
ID("id"),
|
||||
|
||||
/**
|
||||
* The name field.
|
||||
*/
|
||||
NAME("name"),
|
||||
|
||||
/**
|
||||
* distribution set which is set as auto assign distribution set
|
||||
*/
|
||||
AUTOASSIGNDISTRIBUTIONSET("autoAssignDistributionSet", "name", "version");
|
||||
|
||||
|
||||
private final String fieldName;
|
||||
private List<String> subEntityAttributes;
|
||||
private boolean mapField;
|
||||
|
||||
TargetFilterQueryFields(final String fieldName) {
|
||||
this(fieldName, false, Collections.emptyList());
|
||||
}
|
||||
|
||||
TargetFilterQueryFields(final String fieldName, final String... subEntityAttribues) {
|
||||
this(fieldName, false, Arrays.asList(subEntityAttribues));
|
||||
}
|
||||
|
||||
TargetFilterQueryFields(final String fieldName, final boolean mapField, final List<String> subEntityAttribues) {
|
||||
this.fieldName = fieldName;
|
||||
this.mapField = mapField;
|
||||
this.subEntityAttributes = subEntityAttribues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSubEntityAttributes() {
|
||||
return subEntityAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMap() {
|
||||
return mapField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.json.model.targetfilter;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtBaseEntity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* A json annotated rest model for Target to RESTful API representation.
|
||||
*
|
||||
*/
|
||||
@JsonInclude(Include.ALWAYS)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MgmtTargetFilterQuery extends MgmtBaseEntity {
|
||||
|
||||
@JsonProperty(value = "id", required = true)
|
||||
private Long filterId;
|
||||
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private String query;
|
||||
|
||||
@JsonProperty
|
||||
private Long autoAssignDistributionSet;
|
||||
|
||||
/**
|
||||
* @return the filterId
|
||||
*/
|
||||
public Long getFilterId() {
|
||||
return filterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filterId
|
||||
* the filterId to set
|
||||
*/
|
||||
public void setFilterId(final Long filterId) {
|
||||
this.filterId = filterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the query
|
||||
*/
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param query
|
||||
* the query to set
|
||||
*/
|
||||
@JsonIgnore
|
||||
public void setQuery(final String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public Long getAutoAssignDistributionSet() {
|
||||
return autoAssignDistributionSet;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setAutoAssignDistributionSet(final Long autoAssignDistributionSet) {
|
||||
this.autoAssignDistributionSet = autoAssignDistributionSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.json.model.targetfilter;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Request body for target PUT/POST commands.
|
||||
*
|
||||
*/
|
||||
public class MgmtTargetFilterQueryRequestBody {
|
||||
@JsonProperty(required = true)
|
||||
private String name;
|
||||
|
||||
@JsonProperty(required = true)
|
||||
private String query;
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public MgmtTargetFilterQueryRequestBody setName(final String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the filter query
|
||||
*/
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param query
|
||||
* the filter query
|
||||
*/
|
||||
public void setQuery(String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentR
|
||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleAssigment;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -179,6 +180,37 @@ public interface MgmtDistributionSetRestApi {
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
|
||||
|
||||
/**
|
||||
* Handles the GET request to retrieve target filter queries that have the
|
||||
* given distribution set as auto assign DS.
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the distribution set to retrieve the assigned
|
||||
* targets
|
||||
* @param pagingOffsetParam
|
||||
* the offset of list of targets for pagination, might not be
|
||||
* present in the rest request then default value will be applied
|
||||
* @param pagingLimitParam
|
||||
* the limit of the paged request, might not be present in the
|
||||
* rest request then default value will be applied
|
||||
* @param sortParam
|
||||
* the sorting parameter in the request URL, syntax
|
||||
* {@code field:direction, field:direction}
|
||||
* @param rsqlParam
|
||||
* the search name parameter in the request URL, syntax
|
||||
* {@code q=myFilter}
|
||||
* @return status OK if get request is successful with the paged list of
|
||||
* targets
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/autoAssignTargetFilters", produces = {
|
||||
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
|
||||
ResponseEntity<PagedList<MgmtTargetFilterQuery>> getAutoAssignTargetFilterQueries(
|
||||
@PathVariable("distributionSetId") final Long distributionSetId,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
|
||||
|
||||
/**
|
||||
* Handles the POST request of assigning multiple targets to a single
|
||||
* distribution set.
|
||||
|
||||
@@ -104,6 +104,11 @@ public final class MgmtRestConstants {
|
||||
public static final String DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING
|
||||
+ "/distributionsettags";
|
||||
|
||||
/**
|
||||
* The target URL mapping rest resource.
|
||||
*/
|
||||
public static final String TARGET_FILTER_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/targetfilters";
|
||||
|
||||
/**
|
||||
* The tag URL mapping rest resource.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.api;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtId;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* Api for handling target operations.
|
||||
*/
|
||||
@RequestMapping(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)
|
||||
public interface MgmtTargetFilterQueryRestApi {
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving a single target filter.
|
||||
*
|
||||
* @param filterId
|
||||
* the ID of the target filter to retrieve
|
||||
* @return a single target with status OK.
|
||||
*/
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{filterId}", produces = { "application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtTargetFilterQuery> getFilter(@PathVariable("filterId") final Long filterId);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving all filters.
|
||||
*
|
||||
* @param pagingOffsetParam
|
||||
* the offset of list of targets for pagination, might not be
|
||||
* present in the rest request then default value will be applied
|
||||
* @param pagingLimitParam
|
||||
* the limit of the paged request, might not be present in the
|
||||
* rest request then default value will be applied
|
||||
* @param sortParam
|
||||
* the sorting parameter in the request URL, syntax
|
||||
* {@code field:direction, field:direction}
|
||||
* @param rsqlParam
|
||||
* the search parameter in the request URL, syntax
|
||||
* {@code q=name==abc}
|
||||
* @return a list of all targets for a defined or default page request with
|
||||
* status OK. The response is always paged. In any failure the
|
||||
* JsonResponseExceptionHandler is handling the response.
|
||||
*/
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<PagedList<MgmtTargetFilterQuery>> getFilters(
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
|
||||
|
||||
/**
|
||||
* Handles the POST request of creating new target filters. The request body
|
||||
* must always be a list of target filters.
|
||||
*
|
||||
* @param filter
|
||||
* the filters to be created.
|
||||
* @return In case all filters were successfully created the ResponseEntity
|
||||
* with status code 201 with a list of successfully created entities
|
||||
* is returned. In any failure the JsonResponseExceptionHandler is
|
||||
* handling the response.
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtTargetFilterQuery> createFilter(@RequestBody final MgmtTargetFilterQueryRequestBody filter);
|
||||
|
||||
/**
|
||||
* Handles the PUT request of updating a target filter. The ID is within the
|
||||
* URL path of the request. A given ID in the request body is ignored. It's
|
||||
* not possible to set fields to {@code null} values.
|
||||
*
|
||||
* @param filterId
|
||||
* the path parameter which contains the ID of the target filter
|
||||
* @param targetFilterRest
|
||||
* the request body which contains the fields which should be
|
||||
* updated, fields which are not given are ignored for the
|
||||
* update.
|
||||
* @return the updated target filter response which contains all fields
|
||||
* including fields which have not been updated
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/{filterId}", consumes = { "application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtTargetFilterQuery> updateFilter(@PathVariable("filterId") final Long filterId,
|
||||
@RequestBody final MgmtTargetFilterQueryRequestBody targetFilterRest);
|
||||
|
||||
/**
|
||||
* Handles the DELETE request of deleting a target filter.
|
||||
*
|
||||
* @param filterId
|
||||
* the ID of the target filter to be deleted
|
||||
* @return If the given controllerId could exists and could be deleted Http
|
||||
* OK. In any failure the JsonResponseExceptionHandler is handling
|
||||
* the response.
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{filterId}", produces = { "application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<Void> deleteFilter(@PathVariable("filterId") final Long filterId);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving the distribution set for auto
|
||||
* assignment of an specific target filter.
|
||||
*
|
||||
* @param filterId
|
||||
* the ID of the target to retrieve the assigned distribution
|
||||
* @return the assigned distribution set with status OK, if none is assigned
|
||||
* than {@code null} content (e.g. "{}")
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{filterId}/autoAssignDS", produces = { "application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtDistributionSet> getAssignedDistributionSet(@PathVariable("filterId") final Long filterId);
|
||||
|
||||
/**
|
||||
* Handles the POST request for changing distribution set for auto
|
||||
* assignment of a target filter.
|
||||
*
|
||||
* @param filterId
|
||||
* of the target to change
|
||||
* @param dsId
|
||||
* of the Id of the auto assign distribution set
|
||||
* @return http status
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/{filterId}/autoAssignDS", consumes = {
|
||||
"application/hal+json",
|
||||
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(@PathVariable("filterId") final Long filterId,
|
||||
@RequestBody final MgmtId dsId);
|
||||
|
||||
/**
|
||||
* Handles the DELETE request for removing the distribution set for auto
|
||||
* assignment of a target filter.
|
||||
*
|
||||
* @param filterId
|
||||
* of the target to change
|
||||
* @return http status
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{filterId}/autoAssignDS")
|
||||
ResponseEntity<Void> deleteAssignedDistributionSet(@PathVariable("filterId") final Long filterId);
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentR
|
||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleAssigment;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetRestApi;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
@@ -32,12 +33,14 @@ import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -66,6 +69,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
||||
@Autowired
|
||||
private TargetManagement targetManagement;
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryManagement targetFilterQueryManagement;
|
||||
|
||||
@Autowired
|
||||
private DeploymentManagement deployManagament;
|
||||
|
||||
@@ -223,6 +229,37 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
||||
HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PagedList<MgmtTargetFilterQuery>> getAutoAssignTargetFilterQueries(
|
||||
@PathVariable("distributionSetId") Long distributionSetId,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) String sortParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) String rsqlParam) {
|
||||
// check if distribution set exists otherwise throw exception
|
||||
// immediately
|
||||
DistributionSet distributionSet = findDistributionSetWithExceptionIfNotFound(distributionSetId);
|
||||
|
||||
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
|
||||
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
||||
final Sort sorting = PagingUtility.sanitizeTargetSortParam(sortParam);
|
||||
|
||||
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
|
||||
final Page<TargetFilterQuery> targetFilterQueries;
|
||||
if (rsqlParam != null) {
|
||||
targetFilterQueries = this.targetFilterQueryManagement.findTargetFilterQueryByAutoAssignDS(pageable,
|
||||
distributionSet, rsqlParam);
|
||||
} else {
|
||||
targetFilterQueries = this.targetFilterQueryManagement.findTargetFilterQueryByAutoAssignDS(pageable,
|
||||
distributionSet);
|
||||
}
|
||||
|
||||
return new ResponseEntity<>(
|
||||
new PagedList<>(MgmtTargetFilterQueryMapper.toResponse(targetFilterQueries.getContent()),
|
||||
targetFilterQueries.getTotalElements()),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetAssignmentResponseBody> createAssignedTarget(
|
||||
@PathVariable("distributionSetId") final Long distributionSetId,
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
* <p>
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
|
||||
/**
|
||||
* A mapper which maps repository model to RESTful model representation and
|
||||
* back.
|
||||
*
|
||||
*/
|
||||
public final class MgmtTargetFilterQueryMapper {
|
||||
|
||||
private MgmtTargetFilterQueryMapper() {
|
||||
// Utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a response for targets.
|
||||
*
|
||||
* @param filters
|
||||
* list of targets
|
||||
* @return the response
|
||||
*/
|
||||
public static List<MgmtTargetFilterQuery> toResponse(final Iterable<TargetFilterQuery> filters) {
|
||||
final List<MgmtTargetFilterQuery> mappedList = new ArrayList<>();
|
||||
if (filters != null) {
|
||||
for (final TargetFilterQuery filter : filters) {
|
||||
final MgmtTargetFilterQuery response = toResponse(filter);
|
||||
mappedList.add(response);
|
||||
}
|
||||
}
|
||||
return mappedList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a response for target.
|
||||
*
|
||||
* @param filter
|
||||
* the target
|
||||
* @return the response
|
||||
*/
|
||||
public static MgmtTargetFilterQuery toResponse(final TargetFilterQuery filter) {
|
||||
if (filter == null) {
|
||||
return null;
|
||||
}
|
||||
final MgmtTargetFilterQuery targetRest = new MgmtTargetFilterQuery();
|
||||
targetRest.setFilterId(filter.getId());
|
||||
targetRest.setName(filter.getName());
|
||||
targetRest.setQuery(filter.getQuery());
|
||||
|
||||
targetRest.setCreatedBy(filter.getCreatedBy());
|
||||
targetRest.setLastModifiedBy(filter.getLastModifiedBy());
|
||||
|
||||
targetRest.setCreatedAt(filter.getCreatedAt());
|
||||
targetRest.setLastModifiedAt(filter.getLastModifiedAt());
|
||||
|
||||
DistributionSet distributionSet = filter.getAutoAssignDistributionSet();
|
||||
if (distributionSet != null) {
|
||||
targetRest.setAutoAssignDistributionSet(distributionSet.getId());
|
||||
}
|
||||
|
||||
targetRest.add(linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withRel("self"));
|
||||
targetRest.add(linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).postAssignedDistributionSet(filter.getId(),null)).withRel("autoAssignDS"));
|
||||
|
||||
return targetRest;
|
||||
}
|
||||
|
||||
static TargetFilterQuery fromRequest(final EntityFactory entityFactory,
|
||||
final MgmtTargetFilterQueryRequestBody filterRest) {
|
||||
final TargetFilterQuery filter = entityFactory.generateTargetFilterQuery();
|
||||
filter.setName(filterRest.getName());
|
||||
filter.setQuery(filterRest.getQuery());
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
* <p>
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtId;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* REST Resource handling target CRUD operations.
|
||||
*/
|
||||
@RestController
|
||||
public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestApi {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MgmtTargetFilterQueryResource.class);
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryManagement filterManagement;
|
||||
|
||||
@Autowired
|
||||
private DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private EntityFactory entityFactory;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetFilterQuery> getFilter(@PathVariable("filterId") Long filterId) {
|
||||
final TargetFilterQuery findTarget = findFilterWithExceptionIfNotFound(filterId);
|
||||
// to single response include poll status
|
||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(findTarget);
|
||||
|
||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PagedList<MgmtTargetFilterQuery>> getFilters(
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) String sortParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) String rsqlParam) {
|
||||
|
||||
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
|
||||
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
||||
final Sort sorting = PagingUtility.sanitizeTargetSortParam(sortParam);
|
||||
|
||||
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
|
||||
final Slice<TargetFilterQuery> findTargetFiltersAll;
|
||||
final Long countTargetsAll;
|
||||
if (rsqlParam != null) {
|
||||
final Page<TargetFilterQuery> findFilterPage = this.filterManagement
|
||||
.findTargetFilterQueryByFilter(pageable, rsqlParam);
|
||||
countTargetsAll = findFilterPage.getTotalElements();
|
||||
findTargetFiltersAll = findFilterPage;
|
||||
} else {
|
||||
findTargetFiltersAll = this.filterManagement.findAllTargetFilterQuery(pageable);
|
||||
countTargetsAll = this.filterManagement.countAllTargetFilterQuery();
|
||||
}
|
||||
|
||||
final List<MgmtTargetFilterQuery> rest = MgmtTargetFilterQueryMapper
|
||||
.toResponse(findTargetFiltersAll.getContent());
|
||||
return new ResponseEntity<>(new PagedList<MgmtTargetFilterQuery>(rest, countTargetsAll), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetFilterQuery> createFilter(@RequestBody MgmtTargetFilterQueryRequestBody filter) {
|
||||
final TargetFilterQuery createdTarget = this.filterManagement
|
||||
.createTargetFilterQuery(MgmtTargetFilterQueryMapper.fromRequest(entityFactory, filter));
|
||||
|
||||
return new ResponseEntity<>(MgmtTargetFilterQueryMapper.toResponse(createdTarget), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetFilterQuery> updateFilter(@PathVariable("filterId") Long filterId,
|
||||
@RequestBody MgmtTargetFilterQueryRequestBody targetFilterRest) {
|
||||
|
||||
final TargetFilterQuery existingFilter = findFilterWithExceptionIfNotFound(filterId);
|
||||
LOG.debug("updating target filter query {}", existingFilter.getId());
|
||||
if (targetFilterRest.getName() != null) {
|
||||
existingFilter.setName(targetFilterRest.getName());
|
||||
}
|
||||
if (targetFilterRest.getQuery() != null) {
|
||||
existingFilter.setQuery(targetFilterRest.getQuery());
|
||||
}
|
||||
|
||||
final TargetFilterQuery updateFilter = this.filterManagement.updateTargetFilterQuery(existingFilter);
|
||||
|
||||
return new ResponseEntity<>(MgmtTargetFilterQueryMapper.toResponse(updateFilter), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> deleteFilter(@PathVariable("filterId") Long filterId) {
|
||||
final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId);
|
||||
this.filterManagement.deleteTargetFilterQuery(filter.getId());
|
||||
LOG.debug("{} target filter query deleted, return status {}", filterId, HttpStatus.OK);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(@PathVariable("filterId") Long filterId,
|
||||
@RequestBody MgmtId dsId) {
|
||||
final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId);
|
||||
|
||||
DistributionSet distributionSet;
|
||||
distributionSet = distributionSetManagement.findDistributionSetById(dsId.getId());
|
||||
if (distributionSet == null) {
|
||||
throw new EntityNotFoundException("DistributionSet with Id {" + dsId + "} does not exist");
|
||||
}
|
||||
|
||||
filter.setAutoAssignDistributionSet(distributionSet);
|
||||
|
||||
final TargetFilterQuery updateFilter = this.filterManagement.updateTargetFilterQuery(filter);
|
||||
|
||||
return new ResponseEntity<>(MgmtTargetFilterQueryMapper.toResponse(updateFilter), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtDistributionSet> getAssignedDistributionSet(@PathVariable("filterId") Long filterId) {
|
||||
final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId);
|
||||
DistributionSet autoAssignDistributionSet = filter.getAutoAssignDistributionSet();
|
||||
MgmtDistributionSet distributionSetRest = MgmtDistributionSetMapper.toResponse(autoAssignDistributionSet);
|
||||
final HttpStatus retStatus;
|
||||
if (distributionSetRest == null) {
|
||||
retStatus = HttpStatus.NO_CONTENT;
|
||||
} else {
|
||||
retStatus = HttpStatus.OK;
|
||||
}
|
||||
return new ResponseEntity<>(distributionSetRest, retStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> deleteAssignedDistributionSet(@PathVariable("filterId") Long filterId) {
|
||||
final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId);
|
||||
|
||||
filter.setAutoAssignDistributionSet(null);
|
||||
|
||||
this.filterManagement.updateTargetFilterQuery(filter);
|
||||
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
private TargetFilterQuery findFilterWithExceptionIfNotFound(final Long filterId) {
|
||||
final TargetFilterQuery filter = this.filterManagement.findTargetFilterQueryById(filterId);
|
||||
if (filter == null) {
|
||||
throw new EntityNotFoundException("TargetFilterQuery with Id {" + filterId + "} does not exist");
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,11 +30,8 @@ import java.util.Set;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.*;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||
@@ -297,6 +294,25 @@ public class MgmtDistributionSetResourceTest extends AbstractRestIntegrationTest
|
||||
.andExpect(jsonPath("$.content[0].controllerId", equalTo(knownTargetId)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target filters with auto assign DS are returned as persisted in the repository.")
|
||||
public void getAutoAssignTargetFiltersOfDistributionSet() throws Exception {
|
||||
// prepare distribution set
|
||||
final String knownFilterName = "a";
|
||||
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
||||
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
|
||||
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(entityFactory.generateTargetFilterQuery(knownFilterName, "x==y", createdDs));
|
||||
// create some dummy targets which are not assigned or installed
|
||||
targetFilterQueryManagement.createTargetFilterQuery(entityFactory.generateTargetFilterQuery("b", "x==y"));
|
||||
targetFilterQueryManagement.createTargetFilterQuery(entityFactory.generateTargetFilterQuery("c", "x==y"));
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId()
|
||||
+ "/autoAssignTargetFilters")).andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(1)))
|
||||
.andExpect(jsonPath("$.content[0].name", equalTo(knownFilterName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that DS in repository are listed with proper paging properties.")
|
||||
public void getDistributionSetsWithoutAddtionalRequestParameters() throws Exception {
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.model.*;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||
import org.eclipse.hawkbit.rest.exception.MessageNotReadableException;
|
||||
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
|
||||
import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Spring MVC Tests against the MgmtTargetResource.
|
||||
*
|
||||
*/
|
||||
@Features("Component Tests - Management API")
|
||||
@Stories("Target Filter Query Resource")
|
||||
public class MgmtTargetFilterQueryResourceTest extends AbstractRestIntegrationTest {
|
||||
|
||||
private static final String TARGET_DESCRIPTION_TEST = "created in test";
|
||||
|
||||
private static final String JSON_PATH_ROOT = "$";
|
||||
|
||||
// fields, attributes
|
||||
private static final String JSON_PATH_FIELD_ID = ".id";
|
||||
private static final String JSON_PATH_FIELD_NAME = ".name";
|
||||
private static final String JSON_PATH_FIELD_QUERY = ".query";
|
||||
private static final String JSON_PATH_FIELD_CONTENT = ".content";
|
||||
private static final String JSON_PATH_FIELD_SIZE = ".size";
|
||||
private static final String JSON_PATH_FIELD_TOTAL = ".total";
|
||||
private static final String JSON_PATH_FIELD_AUTO_ASSIGN_DS = ".autoAssignDistributionSet";
|
||||
|
||||
// target
|
||||
// $.field
|
||||
static final String JSON_PATH_PAGED_LIST_CONTENT = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTENT;
|
||||
static final String JSON_PATH_PAGED_LIST_SIZE = JSON_PATH_ROOT + JSON_PATH_FIELD_SIZE;
|
||||
static final String JSON_PATH_PAGED_LIST_TOTAL = JSON_PATH_ROOT + JSON_PATH_FIELD_TOTAL;
|
||||
|
||||
private static final String JSON_PATH_NAME = JSON_PATH_ROOT + JSON_PATH_FIELD_NAME;
|
||||
private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID;
|
||||
private static final String JSON_PATH_QUERY = JSON_PATH_ROOT + JSON_PATH_FIELD_QUERY;
|
||||
private static final String JSON_PATH_AUTO_ASSIGN_DS = JSON_PATH_ROOT + JSON_PATH_FIELD_AUTO_ASSIGN_DS;
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Ensures that deletion is executed if permitted.")
|
||||
public void deleteTargetFilterQueryReturnsOK() throws Exception {
|
||||
final String filterName = "filter_01";
|
||||
TargetFilterQuery filterQuery = createSingleTargetFilterQuery(filterName, "name=test_01");
|
||||
|
||||
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId()))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryById(filterQuery.getId());
|
||||
assertThat(tfq).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that deletion is refused with not found if target does not exist.")
|
||||
public void deleteTargetWhichDoesNotExistsLeadsToEntityNotFound() throws Exception {
|
||||
final String notExistingId = "4395";
|
||||
|
||||
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + notExistingId))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that update is refused with not found if target does not exist.")
|
||||
public void updateTargetWhichDoesNotExistsLeadsToEntityNotFound() throws Exception {
|
||||
final String notExistingId = "4395";
|
||||
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + notExistingId).content("{}")
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that update request is reflected by repository.")
|
||||
public void updateTargetFilterQueryQuery() throws Exception {
|
||||
final String filterName = "filter_02";
|
||||
final String filterQuery = "name=test_02";
|
||||
final String filterQuery2 = "name=test_02_changed";
|
||||
final String body = new JSONObject().put("query", filterQuery2).toString();
|
||||
|
||||
// prepare
|
||||
TargetFilterQuery tfq = createSingleTargetFilterQuery(filterName, filterQuery);
|
||||
|
||||
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()).content(body)
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id", equalTo(tfq.getId().intValue())))
|
||||
.andExpect(jsonPath("$.query", equalTo(filterQuery2)))
|
||||
.andExpect(jsonPath("$.name", equalTo(filterName)));
|
||||
|
||||
TargetFilterQuery tfqCheck = targetFilterQueryManagement.findTargetFilterQueryById(tfq.getId());
|
||||
assertThat(tfqCheck.getQuery()).isEqualTo(filterQuery2);
|
||||
assertThat(tfqCheck.getName()).isEqualTo(filterName);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that update request is reflected by repository.")
|
||||
public void updateTargetFilterQueryName() throws Exception {
|
||||
final String filterName = "filter_03";
|
||||
final String filterName2 = "filter_03_changed";
|
||||
final String filterQuery = "name=test_03";
|
||||
final String body = new JSONObject().put("name", filterName2).toString();
|
||||
|
||||
// prepare
|
||||
TargetFilterQuery tfq = entityFactory.generateTargetFilterQuery();
|
||||
tfq.setName(filterName);
|
||||
tfq.setQuery(filterQuery);
|
||||
tfq = targetFilterQueryManagement.createTargetFilterQuery(tfq);
|
||||
|
||||
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()).content(body)
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id", equalTo(tfq.getId().intValue())))
|
||||
.andExpect(jsonPath("$.query", equalTo(filterQuery)))
|
||||
.andExpect(jsonPath("$.name", equalTo(filterName2)));
|
||||
|
||||
TargetFilterQuery tfqCheck = targetFilterQueryManagement.findTargetFilterQueryById(tfq.getId());
|
||||
assertThat(tfqCheck.getQuery()).isEqualTo(filterQuery);
|
||||
assertThat(tfqCheck.getName()).isEqualTo(filterName2);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Ensures that request returns list of filters in defined format.")
|
||||
public void getTargetFilterQueryWithoutAdditionalRequestParameters() throws Exception {
|
||||
final int knownTargetAmount = 3;
|
||||
final String idA = "a";
|
||||
final String idB = "b";
|
||||
final String idC = "c";
|
||||
final String testQuery = "name=test";
|
||||
|
||||
createSingleTargetFilterQuery(idA, testQuery);
|
||||
createSingleTargetFilterQuery(idB, testQuery);
|
||||
createSingleTargetFilterQuery(idC, testQuery);
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)).andExpect(status().isOk())
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(knownTargetAmount)))
|
||||
// idA
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].name", contains(idA)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].query", contains(testQuery)))
|
||||
// idB
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].name", contains(idB)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].query", contains(testQuery)))
|
||||
// idC
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].name", contains(idC)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].query", contains(testQuery)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that request returns list of filters in defined format in size reduced by given limit parameter.")
|
||||
public void getTargetWithPagingLimitRequestParameter() throws Exception {
|
||||
final int limitSize = 1;
|
||||
final int knownTargetAmount = 3;
|
||||
final String idA = "a";
|
||||
final String idB = "b";
|
||||
final String idC = "c";
|
||||
final String testQuery = "name=test";
|
||||
|
||||
createSingleTargetFilterQuery(idA, testQuery);
|
||||
createSingleTargetFilterQuery(idB, testQuery);
|
||||
createSingleTargetFilterQuery(idC, testQuery);
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)
|
||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)))
|
||||
// idA
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].name", contains(idA)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].query", contains(testQuery)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that request returns list of filters in defined format in size reduced by given limit and offset parameter.")
|
||||
public void getTargetWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
||||
final int knownTargetAmount = 5;
|
||||
final int offsetParam = 2;
|
||||
final int expectedSize = knownTargetAmount - offsetParam;
|
||||
final String idC = "c";
|
||||
final String idD = "d";
|
||||
final String idE = "e";
|
||||
final String testQuery = "name=test";
|
||||
|
||||
createSingleTargetFilterQuery("a", testQuery);
|
||||
createSingleTargetFilterQuery("b", testQuery);
|
||||
createSingleTargetFilterQuery(idC, testQuery);
|
||||
createSingleTargetFilterQuery(idD, testQuery);
|
||||
createSingleTargetFilterQuery(idE, testQuery);
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)
|
||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam))
|
||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(knownTargetAmount)))
|
||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)))
|
||||
// idA
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].name", contains(idC)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].query", contains(testQuery)))
|
||||
// idB
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].name", contains(idD)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].query", contains(testQuery)))
|
||||
// idC
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].name", contains(idE)))
|
||||
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].query", contains(testQuery)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSingleTarget() throws Exception {
|
||||
// create first a target which can be retrieved by rest interface
|
||||
final String knownQuery = "name=test01";
|
||||
final String knownName = "someName";
|
||||
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
|
||||
final String hrefPrefix = "http://localhost"+MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING+"/" + tfq.getId();
|
||||
// test
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName)))
|
||||
.andExpect(jsonPath(JSON_PATH_QUERY, equalTo(knownQuery)))
|
||||
.andExpect(jsonPath("$._links.self.href", equalTo(hrefPrefix)))
|
||||
.andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSingleTargetNoExistsResponseNotFound() throws Exception {
|
||||
final String targetIdNotExists = "546546";
|
||||
// test
|
||||
|
||||
final MvcResult mvcResult = mvc
|
||||
.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + targetIdNotExists))
|
||||
.andExpect(status().isNotFound()).andReturn();
|
||||
|
||||
// verify response json exception message
|
||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||
.convertException(mvcResult.getResponse().getContentAsString());
|
||||
assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_REPO_ENTITY_NOT_EXISTS.getKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTargetFilterQueryWithBadPayloadBadRequest() throws Exception {
|
||||
final String notJson = "abc";
|
||||
|
||||
final MvcResult mvcResult = mvc
|
||||
.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING).content(notJson)
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
||||
|
||||
assertThat(targetFilterQueryManagement.countAllTargetFilterQuery()).isEqualTo(0);
|
||||
|
||||
// verify response json exception message
|
||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||
.convertException(mvcResult.getResponse().getContentAsString());
|
||||
assertThat(exceptionInfo.getExceptionClass()).isEqualTo(MessageNotReadableException.class.getName());
|
||||
assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_REST_BODY_NOT_READABLE.getKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAutoAssignDistributionSetToTargetFilterQuery() throws Exception {
|
||||
|
||||
final String knownQuery = "name=test05";
|
||||
final String knownName = "filter05";
|
||||
|
||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
|
||||
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"+tfq.getId()+"/autoAssignDS")
|
||||
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
assertThat(targetFilterQueryManagement.findTargetFilterQueryById(tfq.getId()).getAutoAssignDistributionSet()).isEqualTo(set);
|
||||
|
||||
final String hrefPrefix = "http://localhost"+MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING+"/" + tfq.getId();
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName)))
|
||||
.andExpect(jsonPath(JSON_PATH_QUERY, equalTo(knownQuery)))
|
||||
.andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_DS, equalTo(set.getId().intValue())))
|
||||
.andExpect(jsonPath("$._links.self.href", equalTo(hrefPrefix)))
|
||||
.andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteAutoAssignDistributionSetOfTargetFilterQuery() throws Exception {
|
||||
|
||||
final String knownQuery = "name=test06";
|
||||
final String knownName = "filter06";
|
||||
final String dsName = "testDS";
|
||||
|
||||
final DistributionSet set = testdataFactory.createDistributionSet(dsName);
|
||||
TargetFilterQuery tfq = entityFactory.generateTargetFilterQuery();
|
||||
tfq.setName(knownName);
|
||||
tfq.setQuery(knownQuery);
|
||||
tfq.setAutoAssignDistributionSet(set);
|
||||
tfq = targetFilterQueryManagement.createTargetFilterQuery(tfq);
|
||||
|
||||
assertThat(targetFilterQueryManagement.findTargetFilterQueryById(tfq.getId()).getAutoAssignDistributionSet())
|
||||
.isEqualTo(set);
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"+tfq.getId()+"/autoAssignDS"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(dsName)));
|
||||
|
||||
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"+tfq.getId()+"/autoAssignDS"))
|
||||
.andExpect(status().isNoContent());
|
||||
|
||||
assertThat(targetFilterQueryManagement.findTargetFilterQueryById(tfq.getId()).getAutoAssignDistributionSet())
|
||||
.isNull();
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"+tfq.getId()+"/autoAssignDS"))
|
||||
.andExpect(status().isNoContent());
|
||||
|
||||
|
||||
}
|
||||
|
||||
private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) {
|
||||
final TargetFilterQuery target = entityFactory.generateTargetFilterQuery();
|
||||
target.setName(name);
|
||||
target.setQuery(query);
|
||||
return targetFilterQueryManagement.createTargetFilterQuery(target);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Rollout Management properties.
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties("hawkbit.autoassign")
|
||||
public class AutoAssignProperties {
|
||||
/**
|
||||
* Autoassign scheduler configuration.
|
||||
*/
|
||||
public static class Scheduler {
|
||||
// used by @Scheduled annotation which needs constant
|
||||
public static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.autoassign.scheduler.fixedDelay:60000}";
|
||||
|
||||
/**
|
||||
* Schedule where the autoassign scheduler looks necessary state changes in
|
||||
* milliseconds.
|
||||
*/
|
||||
private long fixedDelay = 60000L;
|
||||
|
||||
public long getFixedDelay() {
|
||||
return fixedDelay;
|
||||
}
|
||||
|
||||
public void setFixedDelay(final long fixedDelay) {
|
||||
this.fixedDelay = fixedDelay;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Scheduler scheduler = new Scheduler();
|
||||
|
||||
public Scheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,6 +104,27 @@ public interface DeploymentManagement {
|
||||
DistributionSetAssignmentResult assignDistributionSet(@NotNull Long dsID,
|
||||
@NotEmpty Collection<TargetWithActionType> targets);
|
||||
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and an action message.
|
||||
*
|
||||
* @param dsID
|
||||
* the ID of the distribution set to assign
|
||||
* @param targets
|
||||
* a list of all targets and their action type
|
||||
* @param actionMessage
|
||||
* an optional message for the action status
|
||||
* @return the assignment result
|
||||
*
|
||||
* @throw IncompleteDistributionSetException if mandatory
|
||||
* {@link SoftwareModuleType} are not assigned as define by the
|
||||
* {@link DistributionSetType}.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
|
||||
DistributionSetAssignmentResult assignDistributionSet(@NotNull Long dsID,
|
||||
@NotEmpty Collection<TargetWithActionType> targets,
|
||||
String actionMessage);
|
||||
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and {@code forcetime}.
|
||||
@@ -364,9 +385,6 @@ public interface DeploymentManagement {
|
||||
* pagination parameter
|
||||
* @param action
|
||||
* to be filtered on
|
||||
* @param withMessages
|
||||
* to <code>true</code> if {@link ActionStatus#getMessages()}
|
||||
* need to be fetched.
|
||||
* @return the corresponding {@link Page} of {@link ActionStatus}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
@@ -463,8 +481,6 @@ public interface DeploymentManagement {
|
||||
*
|
||||
* @param action
|
||||
* to be canceled
|
||||
* @param target
|
||||
* for which the action needs cancellation
|
||||
*
|
||||
* @return generated {@link Action} or <code>null</code> if not active on
|
||||
* {@link Target}.
|
||||
@@ -478,8 +494,6 @@ public interface DeploymentManagement {
|
||||
* Updates a {@link Action} and forces the {@link Action} if it's not
|
||||
* already forced.
|
||||
*
|
||||
* @param targetId
|
||||
* the ID of the target
|
||||
* @param actionId
|
||||
* the ID of the action
|
||||
* @return the updated or the found {@link Action}
|
||||
|
||||
@@ -316,6 +316,30 @@ public interface EntityFactory {
|
||||
*/
|
||||
TargetFilterQuery generateTargetFilterQuery();
|
||||
|
||||
/**
|
||||
* Generates an {@link TargetFilterQuery} without persisting it.
|
||||
*
|
||||
* @param name
|
||||
* name for the filter
|
||||
* @param query
|
||||
* query of the filter
|
||||
* @return {@link TargetFilterQuery} object
|
||||
*/
|
||||
TargetFilterQuery generateTargetFilterQuery(String name, String query);
|
||||
|
||||
/**
|
||||
* Generates an {@link TargetFilterQuery} without persisting it.
|
||||
*
|
||||
* @param name
|
||||
* name for the filter
|
||||
* @param query
|
||||
* query of the filter
|
||||
* @param autoAssignDS
|
||||
* auto assign distribution set
|
||||
* @return {@link TargetFilterQuery} object
|
||||
*/
|
||||
TargetFilterQuery generateTargetFilterQuery(String name, String query, DistributionSet autoAssignDS);
|
||||
|
||||
/**
|
||||
* Generates an empty {@link TargetTag} without persisting it.
|
||||
*
|
||||
|
||||
@@ -13,6 +13,7 @@ import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -70,6 +71,13 @@ public interface TargetFilterQueryManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findAllTargetFilterQuery(@NotNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Counts all target filter queries
|
||||
* @return the number of all target filter queries
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Long countAllTargetFilterQuery();
|
||||
|
||||
/**
|
||||
* Retrieves all target filter query which {@link TargetFilterQuery}.
|
||||
*
|
||||
@@ -77,11 +85,64 @@ public interface TargetFilterQueryManagement {
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @param name
|
||||
* target filter query name
|
||||
* name filter
|
||||
* @return the page with the found {@link TargetFilterQuery}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findTargetFilterQueryByFilters(@NotNull Pageable pageable, String name);
|
||||
Page<TargetFilterQuery> findTargetFilterQueryByName(@NotNull Pageable pageable, String name);
|
||||
|
||||
/**
|
||||
* Retrieves all target filter query which {@link TargetFilterQuery}.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @param rsqlFilter
|
||||
* RSQL filter string
|
||||
* @return the page with the found {@link TargetFilterQuery}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, String rsqlFilter);
|
||||
|
||||
/**
|
||||
* Retrieves all target filter query which {@link TargetFilterQuery}.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @param distributionSet
|
||||
* the auto assign distribution set
|
||||
* @return the page with the found {@link TargetFilterQuery}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
|
||||
DistributionSet distributionSet);
|
||||
|
||||
/**
|
||||
* Retrieves all target filter query which {@link TargetFilterQuery}.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @param distributionSet
|
||||
* the auto assign distribution set
|
||||
* @param rsqlParam
|
||||
* RSQL filter
|
||||
* @return the page with the found {@link TargetFilterQuery}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
|
||||
DistributionSet distributionSet, String rsqlParam);
|
||||
|
||||
/**
|
||||
* Retrieves all target filter query with auto assign DS which {@link TargetFilterQuery}.
|
||||
*
|
||||
*
|
||||
* @return the page with the found {@link TargetFilterQuery}
|
||||
* @param pageable
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(@NotNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Find target filter query by id.
|
||||
|
||||
@@ -242,6 +242,35 @@ public interface TargetManagement {
|
||||
List<TargetIdName> findAllTargetIdsByTargetFilterQuery(@NotNull Pageable pageRequest,
|
||||
@NotNull TargetFilterQuery targetFilterQuery);
|
||||
|
||||
/**
|
||||
* Finds all targets for all the given parameter {@link TargetFilterQuery}
|
||||
* and that don't have the specified assigned distribution set.
|
||||
* and returns not the full target but {@link TargetIdName}.
|
||||
*
|
||||
* @param pageRequest
|
||||
* the pageRequest to enhance the query for paging and sorting
|
||||
* @param targetFilterQuery
|
||||
* {@link TargetFilterQuery}
|
||||
* @return the found {@link TargetIdName}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Page<Target> findAllTargetIdsByTargetFilterQueryAndNonDS(@NotNull Pageable pageRequest,
|
||||
Long distributionSetId,
|
||||
@NotNull TargetFilterQuery targetFilterQuery);
|
||||
|
||||
/**
|
||||
* Counts all targets for all the given parameter {@link TargetFilterQuery}
|
||||
* and that don't have the specified assigned distribution set. and returns
|
||||
* not the full target but {@link TargetIdName}.
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* {@link TargetFilterQuery}
|
||||
* @return the found {@link TargetIdName}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
Long countTargetByTargetFilterQueryAndNonDS(Long distributionSetId,
|
||||
@NotNull TargetFilterQuery targetFilterQuery);
|
||||
|
||||
/**
|
||||
* retrieves {@link Target}s by the assigned {@link DistributionSet} without
|
||||
* details, i.e. NO {@link Target#getTags()} and {@link Target#getActions()}
|
||||
|
||||
@@ -73,6 +73,11 @@ public interface DistributionSet extends NamedVersionedEntity {
|
||||
*/
|
||||
List<Target> getAssignedTargets();
|
||||
|
||||
/**
|
||||
* @return the auto assign target filters
|
||||
*/
|
||||
List<TargetFilterQuery> getAutoAssignFilters();
|
||||
|
||||
/**
|
||||
* @return the installedTargets
|
||||
*/
|
||||
|
||||
@@ -56,4 +56,16 @@ public interface TargetFilterQuery extends TenantAwareBaseEntity {
|
||||
*/
|
||||
void setQuery(String query);
|
||||
|
||||
/**
|
||||
* @return the auto assign {@link DistributionSet} if given.
|
||||
*/
|
||||
DistributionSet getAutoAssignDistributionSet();
|
||||
|
||||
/**
|
||||
* @param distributionSet
|
||||
* the {@link DistributionSet} that should be assigned to a
|
||||
* target when this filter matches.
|
||||
*/
|
||||
void setAutoAssignDistributionSet(DistributionSet distributionSet);
|
||||
|
||||
}
|
||||
|
||||
@@ -175,13 +175,23 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
|
||||
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
|
||||
final Collection<TargetWithActionType> targets) {
|
||||
return assignDistributionSet(dsID, targets, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Modifying
|
||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
|
||||
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
|
||||
final Collection<TargetWithActionType> targets,
|
||||
final String actionMessage) {
|
||||
final JpaDistributionSet set = distributoinSetRepository.findOne(dsID);
|
||||
if (set == null) {
|
||||
throw new EntityNotFoundException(
|
||||
String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID));
|
||||
}
|
||||
|
||||
return assignDistributionSetToTargets(set, targets, null, null);
|
||||
return assignDistributionSetToTargets(set, targets, null, null, actionMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,21 +206,23 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID));
|
||||
}
|
||||
|
||||
return assignDistributionSetToTargets(set, targets, (JpaRollout) rollout, (JpaRolloutGroup) rolloutGroup);
|
||||
return assignDistributionSetToTargets(set, targets, (JpaRollout) rollout, (JpaRolloutGroup) rolloutGroup, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and {@code forcetime}.
|
||||
*
|
||||
* @param dsID
|
||||
* @param set
|
||||
* the ID of the distribution set to assign
|
||||
* @param targets
|
||||
* @param targetsWithActionType
|
||||
* a list of all targets and their action type
|
||||
* @param rollout
|
||||
* the rollout for this assignment
|
||||
* @param rolloutGroup
|
||||
* the rollout group for this assignment
|
||||
* @param actionMessage
|
||||
* an optional message to be written into the action status
|
||||
* @return the assignment result
|
||||
*
|
||||
* @throw IncompleteDistributionSetException if mandatory
|
||||
@@ -219,7 +231,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
*/
|
||||
private DistributionSetAssignmentResult assignDistributionSetToTargets(@NotNull final JpaDistributionSet set,
|
||||
final Collection<TargetWithActionType> targetsWithActionType, final JpaRollout rollout,
|
||||
final JpaRolloutGroup rolloutGroup) {
|
||||
final JpaRolloutGroup rolloutGroup, final String actionMessage) {
|
||||
|
||||
if (!set.isComplete()) {
|
||||
throw new IncompleteDistributionSetException(
|
||||
@@ -292,6 +304,9 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
actionStatus.setAction(action);
|
||||
actionStatus.setOccurredAt(action.getCreatedAt());
|
||||
actionStatus.setStatus(Status.RUNNING);
|
||||
if(actionMessage != null) {
|
||||
actionStatus.addMessage(actionMessage);
|
||||
}
|
||||
actionStatusRepository.save(actionStatus);
|
||||
});
|
||||
|
||||
@@ -346,7 +361,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
* the Target which has been assigned to a distribution set
|
||||
* @param actionId
|
||||
* the action id of the assignment
|
||||
* @param softwareModules
|
||||
* @param modules
|
||||
* the software modules which have been assigned
|
||||
*/
|
||||
private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
|
||||
@@ -364,11 +379,11 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes {@link UpdateAction}s that are no longer necessary and sends
|
||||
* Removes {@link Action}s that are no longer necessary and sends
|
||||
* cancellations to the controller.
|
||||
*
|
||||
* @param myTarget
|
||||
* to override {@link UpdateAction}s
|
||||
* @param targetsIds
|
||||
* to override {@link Action}s
|
||||
*/
|
||||
private Set<Long> overrideObsoleteUpdateActions(final List<Long> targetsIds) {
|
||||
|
||||
@@ -403,7 +418,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
|
||||
return assignDistributionSetToTargets(set, tIDs.stream()
|
||||
.map(t -> new TargetWithActionType(t, actionType, forcedTime)).collect(Collectors.toList()), null,
|
||||
null);
|
||||
null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -95,6 +95,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
@Autowired
|
||||
private DistributionSetMetadataRepository distributionSetMetadataRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryRepository targetFilterQueryRepository;
|
||||
|
||||
@Autowired
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
@@ -182,7 +185,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
// soft delete assigned
|
||||
if (!assigned.isEmpty()) {
|
||||
distributionSetRepository.deleteDistributionSet(assigned.toArray(new Long[assigned.size()]));
|
||||
Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
|
||||
distributionSetRepository.deleteDistributionSet(dsIds);
|
||||
targetFilterQueryRepository.unsetAutoAssignDistributionSet(dsIds);
|
||||
}
|
||||
|
||||
// mark the rest as hard delete
|
||||
|
||||
@@ -132,6 +132,16 @@ public class JpaEntityFactory implements EntityFactory {
|
||||
return new JpaTargetFilterQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetFilterQuery generateTargetFilterQuery(String name, String query) {
|
||||
return new JpaTargetFilterQuery(name, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetFilterQuery generateTargetFilterQuery(String name, String query, DistributionSet autoAssignDS) {
|
||||
return new JpaTargetFilterQuery(name, query, (JpaDistributionSet) autoAssignDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoftwareModuleType generateSoftwareModuleType() {
|
||||
return new JpaSoftwareModuleType();
|
||||
|
||||
@@ -56,6 +56,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
@Autowired
|
||||
private TargetRepository targetRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryRepository targetFilterQueryRepository;
|
||||
|
||||
@Autowired
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
@@ -221,6 +224,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||
tenantConfigurationRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetFilterQueryRepository.deleteByTenantIgnoreCase(tenant);
|
||||
actionRepository.deleteByTenantIgnoreCase(tenant);
|
||||
rolloutGroupRepository.deleteByTenantIgnoreCase(tenant);
|
||||
rolloutRepository.deleteByTenantIgnoreCase(tenant);
|
||||
|
||||
@@ -12,12 +12,14 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryFields;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -33,6 +35,8 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link TargetFilterQueryManagement}.
|
||||
*
|
||||
@@ -67,13 +71,18 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
return convertPage(targetFilterQueryRepository.findAll(pageable), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countAllTargetFilterQuery() {
|
||||
return targetFilterQueryRepository.count();
|
||||
}
|
||||
|
||||
private static Page<TargetFilterQuery> convertPage(final Page<JpaTargetFilterQuery> findAll,
|
||||
final Pageable pageable) {
|
||||
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryByFilters(final Pageable pageable, final String name) {
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryByName(final Pageable pageable, final String name) {
|
||||
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>();
|
||||
if (!Strings.isNullOrEmpty(name)) {
|
||||
specList.add(TargetFilterQuerySpecification.likeName(name));
|
||||
@@ -81,6 +90,41 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, String rsqlFilter) {
|
||||
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>();
|
||||
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
||||
specList.add(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class));
|
||||
}
|
||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
|
||||
DistributionSet distributionSet) {
|
||||
return findTargetFilterQueryByAutoAssignDS(pageable, distributionSet, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
|
||||
DistributionSet distributionSet, String rsqlFilter) {
|
||||
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>();
|
||||
if (distributionSet != null) {
|
||||
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
|
||||
}
|
||||
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
||||
specList.add(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class));
|
||||
}
|
||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(@NotNull Pageable pageable) {
|
||||
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>();
|
||||
specList.add(TargetFilterQuerySpecification.withAutoAssignDS());
|
||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||
}
|
||||
|
||||
private Page<JpaTargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
|
||||
final List<Specification<JpaTargetFilterQuery>> specList) {
|
||||
if (specList == null || specList.isEmpty()) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
@@ -561,6 +562,31 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Target> findAllTargetIdsByTargetFilterQueryAndNonDS(@NotNull Pageable pageRequest,
|
||||
Long distributionSetId, @NotNull TargetFilterQuery targetFilterQuery) {
|
||||
|
||||
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
||||
|
||||
return findTargetsBySpec(
|
||||
(root, cq,
|
||||
cb) -> cb.and(spec.toPredicate(root, cq, cb), TargetSpecifications
|
||||
.hasNotDistributionSetInActions(distributionSetId).toPredicate(root, cq, cb)),
|
||||
pageRequest);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countTargetByTargetFilterQueryAndNonDS(Long distributionSetId, @NotNull TargetFilterQuery targetFilterQuery) {
|
||||
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
||||
final List<Specification<JpaTarget>> specList = new ArrayList<>();
|
||||
specList.add(spec);
|
||||
|
||||
specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId));
|
||||
|
||||
return countByCriteriaAPI(specList);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void destroy() {
|
||||
eventBus.unregister(this);
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -43,4 +45,15 @@ public interface TargetFilterQueryRepository
|
||||
@Transactional
|
||||
<S extends JpaTargetFilterQuery> S save(S entity);
|
||||
|
||||
/**
|
||||
* Sets the auto assign distribution sets to null which match the ds ids.
|
||||
*
|
||||
* @param dsIds
|
||||
* distribution set ids to be set to null
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL where d.autoAssignDistributionSet in :ids")
|
||||
void unsetAutoAssignDistributionSet(@Param("ids") Long... dsIds);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
* Checks if targets need a new distribution set (DS) based on the target filter queries and
|
||||
* assigns the new DS when necessary.
|
||||
* First all target filter queries are listed. For every target filter query (TFQ) the auto assign DS
|
||||
* is retrieved.
|
||||
* All targets get listed per target filter query, that match the TFQ and that don't have the
|
||||
* auto assign DS in their action history.
|
||||
*/
|
||||
@Component
|
||||
public class AutoAssignChecker {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AutoAssignChecker.class);
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryManagement targetFilterQueryManagement;
|
||||
|
||||
@Autowired
|
||||
private TargetManagement targetManagement;
|
||||
|
||||
@Autowired
|
||||
private DeploymentManagement deploymentManagement;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* Maximum for target filter queries with auto assign DS
|
||||
* Maximum for targets that are fetched in one turn
|
||||
*/
|
||||
private static final int PAGE_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* The message which is added to the action status when a distribution set is assigned
|
||||
* to an target. First %s is the name of the target filter.
|
||||
*/
|
||||
private static final String ACTION_MESSAGE = "Auto assignment by target filter: %s";
|
||||
|
||||
/**
|
||||
* Checks all target filter queries with an auto assign distribution set
|
||||
* and triggers the check and assignment to targets that don't have the design DS yet
|
||||
*/
|
||||
public void check() {
|
||||
if(transactionTemplate == null) {
|
||||
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
|
||||
def.setName("autoAssignDSToTargets");
|
||||
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
transactionTemplate = new TransactionTemplate(transactionManager, def);
|
||||
}
|
||||
|
||||
PageRequest pageRequest = new PageRequest(0, PAGE_SIZE);
|
||||
|
||||
Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement
|
||||
.findTargetFilterQueryWithAutoAssignDS(pageRequest);
|
||||
|
||||
for (TargetFilterQuery filterQuery : filterQueries) {
|
||||
checkByTargetFilterQueryAndAssignDS(filterQuery);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the distribution set, gets all controllerIds and assigns the DS
|
||||
* to them.
|
||||
* Catches PersistenceException and own exceptions derived from AbstractServerRtException
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* the target filter query
|
||||
*/
|
||||
private void checkByTargetFilterQueryAndAssignDS(TargetFilterQuery targetFilterQuery) {
|
||||
try {
|
||||
DistributionSet distributionSet = targetFilterQuery.getAutoAssignDistributionSet();
|
||||
|
||||
int count;
|
||||
do {
|
||||
|
||||
count = runTransactionalAssignment(targetFilterQuery, distributionSet.getId());
|
||||
|
||||
} while (count == PAGE_SIZE);
|
||||
|
||||
} catch (PersistenceException | AbstractServerRtException e) {
|
||||
LOGGER.error("Error during auto assign check of target filter query " + targetFilterQuery.getId(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs one page of target assignments within a dedicated transaction
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* the target filter query
|
||||
* @param dsId
|
||||
* distribution set id to assign
|
||||
* @return count of targets
|
||||
*/
|
||||
private int runTransactionalAssignment(TargetFilterQuery targetFilterQuery, Long dsId) {
|
||||
final String actionMessage = String.format(ACTION_MESSAGE, targetFilterQuery.getName());
|
||||
return transactionTemplate.execute(status -> {
|
||||
List<TargetWithActionType> targets = getTargetsWithActionType(targetFilterQuery, dsId, PAGE_SIZE);
|
||||
int count = targets.size();
|
||||
if (count > 0) {
|
||||
deploymentManagement.assignDistributionSet(dsId, targets, actionMessage);
|
||||
}
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all matching targets with the designated action from the target management
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* the query the targets have to match
|
||||
* @param dsId
|
||||
* dsId the targets are not allowed to have in their action
|
||||
* history
|
||||
* @param count
|
||||
* maximum amount of targets to retrieve
|
||||
* @return list of targets with action type
|
||||
*/
|
||||
private List<TargetWithActionType> getTargetsWithActionType(TargetFilterQuery targetFilterQuery, Long dsId, int count) {
|
||||
Page<Target> targets = targetManagement.findAllTargetIdsByTargetFilterQueryAndNonDS(new PageRequest(0, count),
|
||||
dsId, targetFilterQuery);
|
||||
|
||||
return targets.getContent().stream()
|
||||
.map(t -> new TargetWithActionType(t.getControllerId(), Action.ActionType.FORCED,
|
||||
RepositoryModelConstants.NO_FORCE_TIME))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.AutoAssignProperties;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Scheduler to check target filters for auto assignment of distribution sets
|
||||
*/
|
||||
@Component
|
||||
// don't active the auto assign scheduler in test, otherwise it is hard to test
|
||||
@Profile("!test")
|
||||
public class AutoAssignScheduler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AutoAssignScheduler.class);
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Autowired
|
||||
private SystemManagement systemManagement;
|
||||
|
||||
@Autowired
|
||||
private SystemSecurityContext systemSecurityContext;
|
||||
|
||||
@Autowired
|
||||
private AutoAssignChecker autoAssignChecker;
|
||||
|
||||
/**
|
||||
* Scheduler method called by the spring-async mechanism. Retrieves all
|
||||
* tenants from the {@link SystemManagement#findTenants()} and runs for each
|
||||
* tenant the auto assignments defined in the target filter queries
|
||||
* {@link SystemSecurityContext}.
|
||||
*/
|
||||
@Scheduled(initialDelayString = AutoAssignProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = AutoAssignProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
||||
public void autoAssignScheduler() {
|
||||
LOGGER.debug("auto assign schedule checker has been triggered.");
|
||||
// run this code in system code privileged to have the necessary
|
||||
// permission to query and create entities.
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
// workaround eclipselink that is currently not possible to
|
||||
// execute a query without multitenancy if MultiTenant
|
||||
// annotation is used.
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
|
||||
// iterate through all tenants and execute the rollout check for
|
||||
// each tenant separately.
|
||||
final List<String> tenants = systemManagement.findTenants();
|
||||
LOGGER.info("Checking target filter queries for tenants: {}", tenants.size());
|
||||
for (final String tenant : tenants) {
|
||||
tenantAware.runAsTenant(tenant, () -> {
|
||||
|
||||
autoAssignChecker.check();
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
@@ -96,6 +97,9 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
@OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)
|
||||
private List<Target> assignedToTargets;
|
||||
|
||||
@OneToMany(mappedBy = "autoAssignDistributionSet", targetEntity = JpaTargetFilterQuery.class, fetch = FetchType.LAZY)
|
||||
private List<TargetFilterQuery> autoAssignFilters;
|
||||
|
||||
@OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY)
|
||||
private List<TargetInfo> installedAtTargets;
|
||||
|
||||
@@ -196,6 +200,11 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
return assignedToTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TargetFilterQuery> getAutoAssignFilters() {
|
||||
return autoAssignFilters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TargetInfo> getInstalledTargets() {
|
||||
return installedAtTargets;
|
||||
|
||||
@@ -9,13 +9,19 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
|
||||
/**
|
||||
@@ -42,6 +48,10 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
|
||||
@NotNull
|
||||
private String query;
|
||||
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
|
||||
@JoinColumn(name = "auto_assign_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_filter_auto_assign_ds"))
|
||||
private JpaDistributionSet autoAssignDistributionSet;
|
||||
|
||||
public JpaTargetFilterQuery() {
|
||||
// Default constructor for JPA.
|
||||
}
|
||||
@@ -59,6 +69,22 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Target filter query with auto assign distribution set
|
||||
*
|
||||
* @param name
|
||||
* of the {@link TargetFilterQuery}.
|
||||
* @param query
|
||||
* of the {@link TargetFilterQuery}.
|
||||
* @param autoAssignDistributionSet
|
||||
* of the {@link TargetFilterQuery}.
|
||||
*/
|
||||
public JpaTargetFilterQuery(String name, String query, JpaDistributionSet autoAssignDistributionSet) {
|
||||
this.name = name;
|
||||
this.query = query;
|
||||
this.autoAssignDistributionSet = autoAssignDistributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
@@ -78,4 +104,14 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
|
||||
public void setQuery(final String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet getAutoAssignDistributionSet() {
|
||||
return autoAssignDistributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoAssignDistributionSet(DistributionSet distributionSet) {
|
||||
autoAssignDistributionSet = (JpaDistributionSet)distributionSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa.specifications;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery_;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
@@ -37,4 +38,28 @@ public final class TargetFilterQuerySpecification {
|
||||
return cb.like(cb.lower(targetFilterQueryRoot.get(JpaTargetFilterQuery_.name)), searchTextToLower);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link JpaTargetFilterQuery}s based
|
||||
* on is {@link JpaTargetFilterQuery#getName()}.
|
||||
*
|
||||
* @param distributionSet
|
||||
* of the filter
|
||||
* @return the {@link JpaTargetFilterQuery} {@link Specification}
|
||||
*/
|
||||
public static Specification<JpaTargetFilterQuery> byAutoAssignDS(final DistributionSet distributionSet) {
|
||||
return (targetFilterQueryRoot, query, cb) -> cb
|
||||
.equal(targetFilterQueryRoot.get(JpaTargetFilterQuery_.autoAssignDistributionSet), distributionSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link JpaTargetFilterQuery}s based
|
||||
* on is {@link JpaTargetFilterQuery#getName()}.
|
||||
*
|
||||
* @return the {@link JpaTargetFilterQuery} {@link Specification}
|
||||
*/
|
||||
public static Specification<JpaTargetFilterQuery> withAutoAssignDS() {
|
||||
return (targetFilterQueryRoot, query, cb) -> cb
|
||||
.isNotNull(targetFilterQueryRoot.get(JpaTargetFilterQuery_.autoAssignDistributionSet));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,15 @@ import java.util.List;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.criteria.ListJoin;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.SetJoin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||
@@ -210,6 +213,24 @@ public final class TargetSpecifications {
|
||||
distributionSetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link Target}s that don't have the given
|
||||
* distribution set in their action history
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the distribution set which must not be assigned
|
||||
* @return the {@link Target} {@link Specification}
|
||||
*/
|
||||
public static Specification<JpaTarget> hasNotDistributionSetInActions(final Long distributionSetId) {
|
||||
return (targetRoot, query, cb) -> {
|
||||
final ListJoin<JpaTarget, JpaAction> actionsJoin = targetRoot.join(JpaTarget_.actions, JoinType.LEFT);
|
||||
actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id),
|
||||
distributionSetId));
|
||||
|
||||
return cb.isNull(actionsJoin.get(JpaAction_.id));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link Target}s by assigned
|
||||
* distribution set.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE sp_target_filter_query
|
||||
ADD column auto_assign_distribution_set BIGINT;
|
||||
|
||||
ALTER TABLE sp_target_filter_query
|
||||
ADD CONSTRAINT fk_filter_auto_assign_ds
|
||||
FOREIGN KEY (auto_assign_distribution_set)
|
||||
REFERENCES sp_distribution_set
|
||||
ON DELETE SET NULL;
|
||||
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE sp_target_filter_query
|
||||
ADD COLUMN auto_assign_distribution_set BIGINT;
|
||||
|
||||
ALTER TABLE sp_target_filter_query
|
||||
ADD CONSTRAINT fk_filter_auto_assign_ds
|
||||
FOREIGN KEY (auto_assign_distribution_set)
|
||||
REFERENCES sp_distribution_set (id)
|
||||
ON DELETE SET NULL;
|
||||
@@ -8,19 +8,27 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test class for {@link TargetFilterQueryManagement}.
|
||||
*
|
||||
@@ -39,6 +47,22 @@ public class TargetFilterQueryManagenmentTest extends AbstractJpaIntegrationTest
|
||||
targetFilterQueryManagement.findTargetFilterQueryByName(filterName));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test searching a target filter query.")
|
||||
public void searchTargetFilterQuery() {
|
||||
final String filterName = "targetFilterQueryName";
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
|
||||
|
||||
targetFilterQueryManagement
|
||||
.createTargetFilterQuery(new JpaTargetFilterQuery("someOtherFilter", "name==PendingTargets002"));
|
||||
|
||||
List<TargetFilterQuery> results = targetFilterQueryManagement
|
||||
.findTargetFilterQueryByFilter(new PageRequest(0, 10), "name==" + filterName).getContent();
|
||||
assertEquals("Search result should have 1 result", 1, results.size());
|
||||
assertEquals("Retrieved newly created custom target filter", targetFilterQuery, results.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Checks if the EntityAlreadyExistsException is thrown if a targetfilterquery with the same name are created more than once.")
|
||||
public void createDuplicateTargetFilterQuery() {
|
||||
@@ -82,4 +106,142 @@ public class TargetFilterQueryManagenmentTest extends AbstractJpaIntegrationTest
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test assigning a distribution set")
|
||||
public void assignDistributionSet() {
|
||||
final String filterName = "target_filter_02";
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
|
||||
|
||||
final DistributionSet distributionSet = distributionSetManagement.createDistributionSet(new JpaDistributionSet(
|
||||
"dist_Set_01", "0.1", "", null, null
|
||||
));
|
||||
|
||||
targetFilterQuery.setAutoAssignDistributionSet(distributionSet);
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(targetFilterQuery);
|
||||
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryByName(filterName);
|
||||
|
||||
assertEquals("Returns correct distribution set", distributionSet,
|
||||
tfq.getAutoAssignDistributionSet());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test removing distribution set while it has a relation to a target filter query")
|
||||
public void removeAssignDistributionSet() {
|
||||
final String filterName = "target_filter_03";
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
|
||||
|
||||
final DistributionSet distributionSet = distributionSetManagement.createDistributionSet(new JpaDistributionSet(
|
||||
"dist_Set_02", "0.1", "", null, null
|
||||
));
|
||||
|
||||
targetFilterQuery.setAutoAssignDistributionSet(distributionSet);
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(targetFilterQuery);
|
||||
|
||||
// Check if target filter query is there
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryByName(filterName);
|
||||
assertEquals("Returns correct distribution set", distributionSet,
|
||||
tfq.getAutoAssignDistributionSet());
|
||||
|
||||
distributionSetManagement.deleteDistributionSet(distributionSet);
|
||||
|
||||
// Check if auto assign distribution set is null
|
||||
tfq = targetFilterQueryManagement.findTargetFilterQueryByName(filterName);
|
||||
assertNotNull("Returns target filter query", tfq);
|
||||
assertNull("Returns distribution set as null", tfq.getAutoAssignDistributionSet());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test to implicitly remove the auto assign distribution set when the ds is soft deleted")
|
||||
public void implicitlyRemoveAssignDistributionSet() {
|
||||
final String filterName = "target_filter_03";
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet("dist_set");
|
||||
Target target = testdataFactory.createTarget();
|
||||
|
||||
// Assign the distribution set to an target, to force a soft delete in a
|
||||
// later step
|
||||
deploymentManagement.assignDistributionSet(distributionSet.getId(), target.getControllerId());
|
||||
|
||||
targetFilterQueryManagement.createTargetFilterQuery(
|
||||
new JpaTargetFilterQuery(filterName, "name==PendingTargets001", (JpaDistributionSet) distributionSet));
|
||||
|
||||
// Check if target filter query is there with the distribution set
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryByName(filterName);
|
||||
assertEquals("Returns correct distribution set", distributionSet, tfq.getAutoAssignDistributionSet());
|
||||
|
||||
distributionSetManagement.deleteDistributionSet(distributionSet);
|
||||
|
||||
// Check if distribution set is still in the database with deleted flag
|
||||
assertTrue("Distribution set should be deleted",
|
||||
distributionSetManagement.findDistributionSetById(distributionSet.getId()).isDeleted());
|
||||
|
||||
// Check if auto assign distribution set is null
|
||||
tfq = targetFilterQueryManagement.findTargetFilterQueryByName(filterName);
|
||||
assertNotNull("Returns target filter query", tfq);
|
||||
assertNull("Returns distribution set as null", tfq.getAutoAssignDistributionSet());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test finding and auto assign distribution set")
|
||||
public void findFiltersWithDistributionSet() {
|
||||
|
||||
final String filterName = "d";
|
||||
|
||||
assertEquals(0L, targetFilterQueryManagement.countAllTargetFilterQuery().longValue());
|
||||
|
||||
targetFilterQueryManagement.createTargetFilterQuery(new JpaTargetFilterQuery("a", "name==*"));
|
||||
targetFilterQueryManagement.createTargetFilterQuery(new JpaTargetFilterQuery("b", "name==*"));
|
||||
|
||||
final DistributionSet distributionSet = distributionSetManagement
|
||||
.createDistributionSet(new JpaDistributionSet("dist_Set_01", "0.1", "", null, null));
|
||||
final DistributionSet distributionSet2 = distributionSetManagement
|
||||
.createDistributionSet(new JpaDistributionSet("dist_Set_02", "0.1", "", null, null));
|
||||
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement.createTargetFilterQuery(
|
||||
new JpaTargetFilterQuery("c", "name==x", (JpaDistributionSet) distributionSet));
|
||||
|
||||
final TargetFilterQuery tfq2 = targetFilterQueryManagement.createTargetFilterQuery(
|
||||
new JpaTargetFilterQuery(filterName, "name==z*", (JpaDistributionSet) distributionSet2));
|
||||
|
||||
assertEquals(4L, targetFilterQueryManagement.countAllTargetFilterQuery().longValue());
|
||||
|
||||
// check if find works
|
||||
Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findTargetFilterQueryByAutoAssignDS(new PageRequest(0, 500), distributionSet);
|
||||
assertThat(1L).as("Target filter query").isEqualTo(tfqList.getTotalElements());
|
||||
|
||||
assertEquals("Returns correct target filter query", tfq.getId(), tfqList.iterator().next().getId());
|
||||
|
||||
tfq2.setAutoAssignDistributionSet(distributionSet);
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(tfq2);
|
||||
|
||||
// check if find works for two
|
||||
tfqList = targetFilterQueryManagement.findTargetFilterQueryByAutoAssignDS(new PageRequest(0, 500),
|
||||
distributionSet);
|
||||
assertThat(2L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
Iterator<TargetFilterQuery> iterator = tfqList.iterator();
|
||||
assertEquals("Returns correct target filter query 1", tfq.getId(), iterator.next().getId());
|
||||
assertEquals("Returns correct target filter query 2", tfq2.getId(), iterator.next().getId());
|
||||
|
||||
// check if find works with name filter
|
||||
tfqList = targetFilterQueryManagement.findTargetFilterQueryByAutoAssignDS(new PageRequest(0, 500),
|
||||
distributionSet, "name==" + filterName);
|
||||
assertThat(1L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
|
||||
assertEquals("Returns correct target filter query", tfq2.getId(), tfqList.iterator().next().getId());
|
||||
|
||||
// check if find works for all with auto assign DS
|
||||
tfqList = targetFilterQueryManagement.findTargetFilterQueryWithAutoAssignDS(new PageRequest(0, 500));
|
||||
assertThat(2L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
iterator = tfqList.iterator();
|
||||
assertEquals("Returns correct target filter query 1", tfq.getId(), iterator.next().getId());
|
||||
assertEquals("Returns correct target filter query 2", tfq2.getId(), iterator.next().getId());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,16 +22,10 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.*;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetIdName;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -727,6 +721,26 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that targets without given assigned DS are returned from repository.")
|
||||
public void findTargetWithoutAssignedDistributionSet() {
|
||||
final DistributionSet assignedSet = testdataFactory.createDistributionSet("");
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(entityFactory.generateTargetFilterQuery("tfq", "name==*"));
|
||||
List<Target> unassignedTargets = targetManagement
|
||||
.createTargets(testdataFactory.generateTargets(12, "unassigned"));
|
||||
List<Target> assignedTargets = targetManagement.createTargets(testdataFactory.generateTargets(10, "assigned"));
|
||||
|
||||
deploymentManagement.assignDistributionSet(assignedSet, assignedTargets);
|
||||
|
||||
List<Target> result = targetManagement.findAllTargetIdsByTargetFilterQueryAndNonDS(pageReq,
|
||||
assignedSet.getId(), tfq).getContent();
|
||||
assertThat(result)
|
||||
.as("count of targets").hasSize(unassignedTargets.size())
|
||||
.as("contains all targets").containsAll(unassignedTargets);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that targets with given installed DS are returned from repository.")
|
||||
public void findTargetByInstalledDistributionSet() {
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Step;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test class for {@link AutoAssignChecker}.
|
||||
*
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Auto assign checker")
|
||||
public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private AutoAssignChecker autoAssignChecker;
|
||||
|
||||
@Test
|
||||
@Description("Test auto assignment of a DS to filtered targets")
|
||||
public void checkAutoAssign() {
|
||||
|
||||
final DistributionSet setA = testdataFactory.createDistributionSet("dsA"); // will be auto assigned
|
||||
final DistributionSet setB = testdataFactory.createDistributionSet("dsB");
|
||||
|
||||
// target filter query that matches all targets
|
||||
TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.createTargetFilterQuery(new JpaTargetFilterQuery("filterA", "name==*"));
|
||||
targetFilterQuery.setAutoAssignDistributionSet(setA);
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(targetFilterQuery);
|
||||
|
||||
|
||||
final String targetDsAIdPref = "targ";
|
||||
List<Target> targets = targetManagement.createTargets(
|
||||
testdataFactory.generateTargets(100, targetDsAIdPref, targetDsAIdPref.concat(" description")));
|
||||
int targetsCount = targets.size();
|
||||
|
||||
// assign set A to first 10 targets
|
||||
deploymentManagement.assignDistributionSet(setA, targets.subList(0, 10));
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setA, targets.subList(0, 10), targetsCount);
|
||||
|
||||
// assign set B to first 5 targets
|
||||
// they have now 2 DS in their action history and should not get updated with dsA
|
||||
deploymentManagement.assignDistributionSet(setB, targets.subList(0, 5));
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setB, targets.subList(0, 5), targetsCount);
|
||||
|
||||
// assign set B to next 10 targets
|
||||
deploymentManagement.assignDistributionSet(setB, targets.subList(10, 20));
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setB, targets.subList(10, 20), targetsCount);
|
||||
|
||||
// Count the number of targets that will be assigned with setA
|
||||
assertThat(targetManagement.countTargetByTargetFilterQueryAndNonDS(setA.getId(), targetFilterQuery))
|
||||
.isEqualTo(90);
|
||||
|
||||
// Run the check
|
||||
autoAssignChecker.check();
|
||||
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setA, targets.subList(5, 100), targetsCount);
|
||||
|
||||
// first 5 should keep their dsB, because they already had the dsA once
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setB, targets.subList(0, 5), targetsCount);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test auto assignment of an incomplete DS to filtered targets, that causes failures")
|
||||
public void checkAutoAssignWithFailures() {
|
||||
|
||||
// incomplete distribution set that will be assigned
|
||||
final DistributionSet setF = distributionSetManagement
|
||||
.createDistributionSet(entityFactory.generateDistributionSet("dsA", "1", "incomplete ds",
|
||||
testdataFactory.findOrCreateDefaultTestDsType(), null));
|
||||
final DistributionSet setA = testdataFactory.createDistributionSet("dsA");
|
||||
final DistributionSet setB = testdataFactory.createDistributionSet("dsB");
|
||||
|
||||
final String targetDsAIdPref = "targA";
|
||||
final String targetDsFIdPref = "targB";
|
||||
|
||||
// target filter query that matches first bunch of targets, that should
|
||||
// fail
|
||||
targetFilterQueryManagement.createTargetFilterQuery(
|
||||
new JpaTargetFilterQuery("filterA", "id==" + targetDsFIdPref + "*", (JpaDistributionSet) setF));
|
||||
|
||||
// target filter query that matches failed bunch of targets
|
||||
targetFilterQueryManagement.createTargetFilterQuery(
|
||||
new JpaTargetFilterQuery("filterB", "id==" + targetDsAIdPref + "*", (JpaDistributionSet) setA));
|
||||
|
||||
List<Target> targetsF = targetManagement.createTargets(
|
||||
testdataFactory.generateTargets(10, targetDsFIdPref, targetDsFIdPref.concat(" description")));
|
||||
|
||||
List<Target> targetsA = targetManagement.createTargets(
|
||||
testdataFactory.generateTargets(10, targetDsAIdPref, targetDsAIdPref.concat(" description")));
|
||||
|
||||
int targetsCount = targetsA.size() + targetsF.size();
|
||||
|
||||
// assign set B to first 5 targets of fail group
|
||||
deploymentManagement.assignDistributionSet(setB, targetsF.subList(0, 5));
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setB, targetsF.subList(0, 5), targetsCount);
|
||||
|
||||
// Run the check
|
||||
autoAssignChecker.check();
|
||||
|
||||
// first 5 targets of the fail group should still have setB
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setB, targetsF.subList(0, 5), targetsCount);
|
||||
|
||||
// all targets of A group should have received setA
|
||||
verifyThatTargetsHaveDistributionSetAssignment(setA, targetsA, targetsCount);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param set the expected distribution set
|
||||
* @param targets the targets that should have it
|
||||
*/
|
||||
@Step
|
||||
private void verifyThatTargetsHaveDistributionSetAssignment(final DistributionSet set, List<Target> targets, int count) {
|
||||
List<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toList());
|
||||
|
||||
Slice<Target> targetsAll = targetManagement.findTargetsAll(new PageRequest(0, 1000));
|
||||
assertThat(targetsAll).as("Count of targets").hasSize(count);
|
||||
|
||||
for (Target target : targetsAll) {
|
||||
if(targetIds.contains(target.getId())) {
|
||||
assertThat(target.getAssignedDistributionSet()).as("assigned DS").isEqualTo(set);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -263,9 +263,9 @@ public class CommonDialogWindow extends Window {
|
||||
|
||||
if (field instanceof Table) {
|
||||
((Table) field).addItemSetChangeListener(new ChangeListener(field));
|
||||
} else {
|
||||
field.addValueChangeListener(new ChangeListener(field));
|
||||
}
|
||||
field.addValueChangeListener(new ChangeListener(field));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.common.detailslayout;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.data.Item;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
|
||||
import com.vaadin.data.util.IndexedContainer;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.VaadinSessionScope;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
|
||||
/**
|
||||
*
|
||||
* DistributionSet TargetFilterQuery table
|
||||
*
|
||||
*/
|
||||
|
||||
@SpringComponent
|
||||
@VaadinSessionScope
|
||||
public class TargetFilterQueryDetailsTable extends Table {
|
||||
|
||||
private static final long serialVersionUID = 2913758299611837718L;
|
||||
|
||||
private static final String TFQ_NAME = "name";
|
||||
private static final String TFQ_QUERY = "query";
|
||||
|
||||
private I18N i18n;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param i18n
|
||||
*/
|
||||
public void init(final I18N i18n) {
|
||||
this.i18n = i18n;
|
||||
createTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate software module metadata.
|
||||
*
|
||||
* @param distributionSet the selected distribution set
|
||||
*/
|
||||
public void populateTableByDistributionSet(final DistributionSet distributionSet) {
|
||||
removeAllItems();
|
||||
if (null == distributionSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
Container dataSource = getContainerDataSource();
|
||||
List<TargetFilterQuery> filters = distributionSet.getAutoAssignFilters();
|
||||
filters.forEach(query -> {
|
||||
Object itemId = dataSource.addItem();
|
||||
Item item = dataSource.getItem(itemId);
|
||||
item.getItemProperty(TFQ_NAME).setValue(query.getName());
|
||||
item.getItemProperty(TFQ_QUERY).setValue(query.getQuery());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_NO_STRIPES);
|
||||
addStyleName(SPUIStyleDefinitions.SW_MODULE_TABLE);
|
||||
addStyleName("details-layout");
|
||||
setSelectable(false);
|
||||
setImmediate(true);
|
||||
setContainerDataSource(getDistSetContainer());
|
||||
setColumnHeaderMode(ColumnHeaderMode.EXPLICIT);
|
||||
addTableHeader();
|
||||
setSizeFull();
|
||||
// same as height of other tabs in details tabsheet
|
||||
setHeight(116, Unit.PIXELS);
|
||||
}
|
||||
|
||||
private IndexedContainer getDistSetContainer() {
|
||||
final IndexedContainer container = new IndexedContainer();
|
||||
container.addContainerProperty(TFQ_NAME, String.class, "");
|
||||
container.addContainerProperty(TFQ_QUERY, String.class, "");
|
||||
setColumnExpandRatio(TFQ_NAME, 0.4F);
|
||||
setColumnAlignment(TFQ_NAME, Align.LEFT);
|
||||
setColumnExpandRatio(TFQ_QUERY, 0.6F);
|
||||
setColumnAlignment(TFQ_QUERY, Align.LEFT);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private void addTableHeader() {
|
||||
setColumnHeader(TFQ_NAME, i18n.get("header.target.filter.name"));
|
||||
setColumnHeader(TFQ_QUERY, i18n.get("header.target.filter.query"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,9 @@ package org.eclipse.hawkbit.ui.components;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
|
||||
/**
|
||||
* Proxy for {@link DistributionSet}.
|
||||
@@ -39,6 +42,33 @@ public class ProxyDistribution {
|
||||
private String version;
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* Creates an empty proxy distribution set
|
||||
*/
|
||||
public ProxyDistribution() {
|
||||
// Default constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new proxy distribution set by using the values from a distribution set
|
||||
* @param distributionSet the source distribution set
|
||||
*/
|
||||
public ProxyDistribution(DistributionSet distributionSet) {
|
||||
setName(distributionSet.getName());
|
||||
setDescription(distributionSet.getDescription());
|
||||
setDistId(distributionSet.getId());
|
||||
setId(distributionSet.getId());
|
||||
setVersion(distributionSet.getVersion());
|
||||
setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
||||
setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
||||
setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(distributionSet));
|
||||
setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(distributionSet));
|
||||
setNameVersion(
|
||||
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
|
||||
setIsComplete(distributionSet.isComplete());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the nameVersion
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@ public class ProxyTargetFilter {
|
||||
private String createdBy;
|
||||
private String lastModifiedBy;
|
||||
private String query;
|
||||
private ProxyDistribution autoAssignDistributionSet;
|
||||
|
||||
public String getCreatedDate() {
|
||||
return createdDate;
|
||||
@@ -90,4 +91,11 @@ public class ProxyTargetFilter {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public ProxyDistribution getAutoAssignDistributionSet() {
|
||||
return autoAssignDistributionSet;
|
||||
}
|
||||
|
||||
public void setAutoAssignDistributionSet(ProxyDistribution autoAssignDistributionSet) {
|
||||
this.autoAssignDistributionSet = autoAssignDistributionSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout;
|
||||
import org.eclipse.hawkbit.ui.common.detailslayout.DistributionSetMetadatadetailslayout;
|
||||
import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable;
|
||||
import org.eclipse.hawkbit.ui.common.detailslayout.TargetFilterQueryDetailsTable;
|
||||
import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
|
||||
@@ -91,6 +92,8 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
|
||||
private DistributionSetMetadatadetailslayout dsMetadataTable;
|
||||
|
||||
private TargetFilterQueryDetailsTable tfqDetailsTable;
|
||||
|
||||
private VerticalLayout tagsLayout;
|
||||
|
||||
private final Map<String, StringBuilder> assignedSWModule = new HashMap<>();
|
||||
@@ -103,9 +106,14 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
softwareModuleTable = new SoftwareModuleDetailsTable();
|
||||
softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(),
|
||||
manageDistUIState);
|
||||
|
||||
dsMetadataTable = new DistributionSetMetadatadetailslayout();
|
||||
dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout,
|
||||
entityFactory);
|
||||
|
||||
tfqDetailsTable = new TargetFilterQueryDetailsTable();
|
||||
tfqDetailsTable.init(getI18n());
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
@@ -120,6 +128,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
populateModule();
|
||||
populateTags();
|
||||
populateMetadataDetails();
|
||||
populateTargetFilterQueries();
|
||||
}
|
||||
|
||||
private void populateModule() {
|
||||
@@ -268,6 +277,10 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
dsMetadataTable.populateDSMetadata(getSelectedBaseEntity());
|
||||
}
|
||||
|
||||
protected void populateTargetFilterQueries() {
|
||||
tfqDetailsTable.populateTableByDistributionSet(getSelectedBaseEntity());
|
||||
}
|
||||
|
||||
private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) {
|
||||
final VerticalLayout detailsTabLayout = getDetailsLayout();
|
||||
detailsTabLayout.removeAllComponents();
|
||||
@@ -323,6 +336,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
detailsTab.addTab(createTagsLayout(), getI18n().get("caption.tags.tab"), null);
|
||||
detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null);
|
||||
detailsTab.addTab(dsMetadataTable, getI18n().get("caption.metadata"), null);
|
||||
detailsTab.addTab(tfqDetailsTable, getI18n().get("caption.auto.assignment.ds"), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,10 +20,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -48,6 +46,7 @@ public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
||||
private transient Page<DistributionSet> firstPageDistributionSets = null;
|
||||
|
||||
private DistributionSetType distributionSetType = null;
|
||||
private Boolean dsComplete = null;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -69,6 +68,9 @@ public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
||||
distributionSetType = (DistributionSetType) queryConfig
|
||||
.get(SPUIDefinitions.FILTER_BY_DISTRIBUTION_SET_TYPE);
|
||||
}
|
||||
if(null != queryConfig.get(SPUIDefinitions.FILTER_BY_DS_COMPLETE)) {
|
||||
dsComplete = (Boolean)queryConfig.get(SPUIDefinitions.FILTER_BY_DS_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sortStates.length > 0) {
|
||||
@@ -96,27 +98,17 @@ public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
||||
} else if (Strings.isNullOrEmpty(searchText)) {
|
||||
// if no search filters available
|
||||
distBeans = getDistributionSetManagement().findDistributionSetsByDeletedAndOrCompleted(
|
||||
new OffsetBasedPageRequest(startIndex, count, sort), false, null);
|
||||
new OffsetBasedPageRequest(startIndex, count, sort), false, dsComplete);
|
||||
} else {
|
||||
final DistributionSetFilter distributionSetFilter = new DistributionSetFilterBuilder().setIsDeleted(false)
|
||||
.setIsComplete(dsComplete)
|
||||
.setSearchText(searchText).setSelectDSWithNoTag(Boolean.FALSE).setType(distributionSetType).build();
|
||||
distBeans = getDistributionSetManagement().findDistributionSetsByFilters(
|
||||
new PageRequest(startIndex / count, count, sort), distributionSetFilter);
|
||||
}
|
||||
|
||||
for (final DistributionSet distributionSet : distBeans) {
|
||||
final ProxyDistribution proxyDistribution = new ProxyDistribution();
|
||||
proxyDistribution.setName(distributionSet.getName());
|
||||
proxyDistribution.setDescription(distributionSet.getDescription());
|
||||
proxyDistribution.setDistId(distributionSet.getId());
|
||||
proxyDistribution.setId(distributionSet.getId());
|
||||
proxyDistribution.setVersion(distributionSet.getVersion());
|
||||
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
||||
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
||||
proxyDistribution.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(distributionSet));
|
||||
proxyDistribution.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(distributionSet));
|
||||
proxyDistribution.setIsComplete(distributionSet.isComplete());
|
||||
proxyDistributions.add(proxyDistribution);
|
||||
proxyDistributions.add(new ProxyDistribution(distributionSet));
|
||||
}
|
||||
return proxyDistributions;
|
||||
}
|
||||
@@ -132,9 +124,10 @@ public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
||||
if (Strings.isNullOrEmpty(searchText) && null == distributionSetType) {
|
||||
// if no search filters available
|
||||
firstPageDistributionSets = getDistributionSetManagement().findDistributionSetsByDeletedAndOrCompleted(
|
||||
new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort), false, null);
|
||||
new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort), false, dsComplete);
|
||||
} else {
|
||||
final DistributionSetFilter distributionSetFilter = new DistributionSetFilterBuilder().setIsDeleted(false)
|
||||
.setIsComplete(dsComplete)
|
||||
.setSearchText(searchText).setSelectDSWithNoTag(Boolean.FALSE).setType(distributionSetType).build();
|
||||
firstPageDistributionSets = getDistributionSetManagement().findDistributionSetsByFilters(
|
||||
new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort), distributionSetFilter);
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.filtermanagement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
|
||||
import org.eclipse.hawkbit.ui.distributions.dstable.ManageDistBeanQuery;
|
||||
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.TableColumn;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
import org.vaadin.spring.events.EventScope;
|
||||
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Table for selecting a distribution set.
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class DistributionSetSelectTable extends Table {
|
||||
|
||||
private static final long serialVersionUID = -4307487829435471759L;
|
||||
|
||||
@Autowired
|
||||
private I18N i18n;
|
||||
|
||||
@Autowired
|
||||
private transient EventBus.SessionEventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private ManageDistUIState manageDistUIState;
|
||||
|
||||
private Container container;
|
||||
|
||||
/**
|
||||
* Initialize the component.
|
||||
*/
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
setStyleName("sp-table");
|
||||
setSizeFull();
|
||||
setSelectable(true);
|
||||
setMultiSelect(false);
|
||||
setImmediate(true);
|
||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_SMALL);
|
||||
populateTableData();
|
||||
setColumnCollapsingAllowed(false);
|
||||
setColumnProperties();
|
||||
setId(UIComponentIdProvider.DIST_SET_SELECT_TABLE_ID);
|
||||
eventBus.subscribe(this);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void destroy() {
|
||||
eventBus.unsubscribe(this);
|
||||
}
|
||||
|
||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||
void onEvents(final List<?> events) {
|
||||
final Object firstEvent = events.get(0);
|
||||
if (DistributionCreatedEvent.class.isInstance(firstEvent)
|
||||
|| DistributionDeletedEvent.class.isInstance(firstEvent)) {
|
||||
refreshDistributions();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateTableData() {
|
||||
container = createContainer();
|
||||
addContainerproperties();
|
||||
setContainerDataSource(container);
|
||||
setColumnProperties();
|
||||
|
||||
}
|
||||
|
||||
protected Container createContainer() {
|
||||
|
||||
final Map<String, Object> queryConfiguration = prepareQueryConfigFilters();
|
||||
final BeanQueryFactory<ManageDistBeanQuery> distributionQF = new BeanQueryFactory<>(ManageDistBeanQuery.class);
|
||||
|
||||
distributionQF.setQueryConfiguration(queryConfiguration);
|
||||
return new LazyQueryContainer(
|
||||
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME),
|
||||
distributionQF);
|
||||
}
|
||||
|
||||
private void addContainerproperties() {
|
||||
/* Create HierarchicalContainer container */
|
||||
container.addContainerProperty(SPUILabelDefinitions.NAME, String.class, null);
|
||||
container.addContainerProperty(SPUILabelDefinitions.VAR_VERSION, String.class, null);
|
||||
}
|
||||
|
||||
private List<TableColumn> getVisbleColumns() {
|
||||
final List<TableColumn> columnList = new ArrayList<>();
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.NAME, i18n.get("header.name"), 0.6F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VERSION, i18n.get("header.version"), 0.4F));
|
||||
return columnList;
|
||||
|
||||
}
|
||||
|
||||
private void setColumnProperties() {
|
||||
final List<TableColumn> columnList = getVisbleColumns();
|
||||
final List<Object> swColumnIds = new ArrayList<>();
|
||||
for (final TableColumn column : columnList) {
|
||||
setColumnHeader(column.getColumnPropertyId(), column.getColumnHeader());
|
||||
setColumnExpandRatio(column.getColumnPropertyId(), column.getExpandRatio());
|
||||
swColumnIds.add(column.getColumnPropertyId());
|
||||
}
|
||||
setVisibleColumns(swColumnIds.toArray());
|
||||
}
|
||||
|
||||
private Map<String, Object> prepareQueryConfigFilters() {
|
||||
final Map<String, Object> queryConfig = new HashMap<>();
|
||||
manageDistUIState.getManageDistFilters().getSearchText()
|
||||
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
|
||||
|
||||
if (null != manageDistUIState.getManageDistFilters().getClickedDistSetType()) {
|
||||
queryConfig.put(SPUIDefinitions.FILTER_BY_DISTRIBUTION_SET_TYPE,
|
||||
manageDistUIState.getManageDistFilters().getClickedDistSetType());
|
||||
}
|
||||
|
||||
queryConfig.put(SPUIDefinitions.FILTER_BY_DS_COMPLETE, Boolean.TRUE);
|
||||
|
||||
return queryConfig;
|
||||
}
|
||||
|
||||
private void refreshDistributions() {
|
||||
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
|
||||
final int size = dsContainer.size();
|
||||
if (size < SPUIDefinitions.MAX_TABLE_ENTRIES) {
|
||||
refreshTablecontainer();
|
||||
}
|
||||
if (size != 0) {
|
||||
setData(SPUIDefinitions.DATA_AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
private Object getItemIdToSelect() {
|
||||
if (manageDistUIState.getSelectedDistributions().isPresent()) {
|
||||
return manageDistUIState.getSelectedDistributions().get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void selectRow() {
|
||||
setValue(getItemIdToSelect());
|
||||
}
|
||||
|
||||
private void refreshTablecontainer() {
|
||||
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
|
||||
dsContainer.refresh();
|
||||
selectRow();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.filtermanagement;
|
||||
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
import org.eclipse.hawkbit.ui.common.builder.WindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
||||
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
|
||||
import com.vaadin.data.Property;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Creates a dialog window to select the distribution set for a target filter query.
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class DistributionSetSelectWindow
|
||||
implements CommonDialogWindow.SaveDialogCloseListener, Property.ValueChangeListener {
|
||||
|
||||
private static final long serialVersionUID = 4752345414134989396L;
|
||||
|
||||
@Autowired
|
||||
private I18N i18n;
|
||||
|
||||
@Autowired
|
||||
private DistributionSetSelectTable dsTable;
|
||||
|
||||
@Autowired
|
||||
private transient EventBus.SessionEventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private transient DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private transient TargetManagement targetManagement;
|
||||
|
||||
@Autowired
|
||||
private transient TargetFilterQueryManagement targetFilterQueryManagement;
|
||||
|
||||
private CommonDialogWindow window;
|
||||
private CheckBox checkBox;
|
||||
private VerticalLayout verticalLayout;
|
||||
private Long tfqId;
|
||||
|
||||
private void init() {
|
||||
Label label = new Label(i18n.get("label.auto.assign.description"));
|
||||
|
||||
checkBox = new CheckBox(i18n.get("label.auto.assign.enable"));
|
||||
checkBox.setId(UIComponentIdProvider.DIST_SET_SELECT_ENABLE_ID);
|
||||
checkBox.setImmediate(true);
|
||||
checkBox.addValueChangeListener(this);
|
||||
|
||||
verticalLayout = new VerticalLayout();
|
||||
verticalLayout.addComponent(label);
|
||||
verticalLayout.addComponent(checkBox);
|
||||
verticalLayout.addComponent(dsTable);
|
||||
|
||||
window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW)
|
||||
.caption(i18n.get("caption.select.auto.assign.dist")).content(verticalLayout).layout(verticalLayout)
|
||||
.i18n(i18n).saveDialogCloseListener(this).buildCommonDialogWindow();
|
||||
window.setId(UIComponentIdProvider.DIST_SET_SELECT_WINDOW_ID);
|
||||
}
|
||||
|
||||
public void setValue(DistributionSetIdName distSet) {
|
||||
dsTable.setVisible(distSet != null);
|
||||
checkBox.setValue(distSet != null);
|
||||
dsTable.setValue(distSet);
|
||||
dsTable.setCurrentPageFirstItemId(distSet);
|
||||
}
|
||||
|
||||
public DistributionSetIdName getValue() {
|
||||
if (checkBox.getValue()) {
|
||||
return (DistributionSetIdName) dsTable.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a distribution set select window for the given target filter query
|
||||
*
|
||||
* @param tfqId
|
||||
* target filter query id
|
||||
*/
|
||||
public void showForTargetFilter(Long tfqId) {
|
||||
this.tfqId = tfqId;
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryById(tfqId);
|
||||
if(tfq == null) {
|
||||
throw new IllegalStateException("TargetFilterQuery does not exist for the given id");
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
DistributionSet distributionSet = tfq.getAutoAssignDistributionSet();
|
||||
if(distributionSet != null) {
|
||||
setValue(DistributionSetIdName.generate(distributionSet));
|
||||
} else {
|
||||
setValue(null);
|
||||
}
|
||||
|
||||
window.setWidth(40.0F, Sizeable.Unit.PERCENTAGE);
|
||||
UI.getCurrent().addWindow(window);
|
||||
window.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is triggered when the checkbox value changes
|
||||
*
|
||||
* @param event
|
||||
* change event
|
||||
*/
|
||||
@Override
|
||||
public void valueChange(Property.ValueChangeEvent event) {
|
||||
dsTable.setVisible(checkBox.getValue());
|
||||
if (window != null) {
|
||||
window.center();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is triggered when the save button is clicked
|
||||
*
|
||||
* @return whether the click should be allowed
|
||||
*/
|
||||
@Override
|
||||
public boolean canWindowSaveOrUpdate() {
|
||||
return !checkBox.getValue() || dsTable.getValue() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called when the new value should be saved after the save button has
|
||||
* been clicked
|
||||
*/
|
||||
@Override
|
||||
public void saveOrUpdate() {
|
||||
if(checkBox.getValue() && dsTable.getValue() != null) {
|
||||
DistributionSetIdName ds = (DistributionSetIdName) dsTable.getValue();
|
||||
updateTargetFilterQueryDS(tfqId, ds.getId());
|
||||
|
||||
} else if(!checkBox.getValue()) {
|
||||
updateTargetFilterQueryDS(tfqId, null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateTargetFilterQueryDS(final Long targetFilterQueryId, final Long dsId) {
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.findTargetFilterQueryById(targetFilterQueryId);
|
||||
|
||||
|
||||
|
||||
if(dsId != null) {
|
||||
confirmWithConsequencesDialog(tfq, dsId);
|
||||
} else {
|
||||
tfq.setAutoAssignDistributionSet(null);
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(tfq);
|
||||
eventBus.publish(this, CustomFilterUIEvent.UPDATED_TARGET_FILTER_QUERY);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void confirmWithConsequencesDialog(TargetFilterQuery tfq, final Long dsId) {
|
||||
|
||||
ConfirmConsequencesDialog dialog = new ConfirmConsequencesDialog(tfq, dsId, new ConfirmCallback() {
|
||||
@Override
|
||||
public void onConfirmResult(boolean accepted) {
|
||||
if(accepted) {
|
||||
tfq.setAutoAssignDistributionSet(distributionSetManagement.findDistributionSetById(dsId));
|
||||
targetFilterQueryManagement.updateTargetFilterQuery(tfq);
|
||||
eventBus.publish(this, CustomFilterUIEvent.UPDATED_TARGET_FILTER_QUERY);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setWidth(40.0F, Sizeable.Unit.PERCENTAGE);
|
||||
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
dialog.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A dialog that displays how many targets will be assigned immediately with the
|
||||
*/
|
||||
private class ConfirmConsequencesDialog extends Window implements Button.ClickListener {
|
||||
|
||||
private static final long serialVersionUID = 7738545414137389326L;
|
||||
|
||||
private TargetFilterQuery targetFilterQuery;
|
||||
private Long distributionSetId;
|
||||
|
||||
private Button okButton;
|
||||
private Button cancelButton;
|
||||
|
||||
private ConfirmCallback callback;
|
||||
|
||||
public ConfirmConsequencesDialog(TargetFilterQuery targetFilterQuery, final Long dsId, ConfirmCallback callback) {
|
||||
super(i18n.get("caption.confirm.assign.consequences"));
|
||||
|
||||
this.callback = callback;
|
||||
this.targetFilterQuery = targetFilterQuery;
|
||||
this.distributionSetId = dsId;
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setId(UIComponentIdProvider.DIST_SET_SELECT_CONS_WINDOW_ID);
|
||||
setModal(true);
|
||||
setResizable(false);
|
||||
|
||||
VerticalLayout layout = new VerticalLayout();
|
||||
layout.setSpacing(true);
|
||||
layout.setMargin(true);
|
||||
setContent(layout);
|
||||
|
||||
Long targetsCount = targetManagement.countTargetByTargetFilterQueryAndNonDS(distributionSetId, targetFilterQuery);
|
||||
Label mainTextLabel;
|
||||
if(targetsCount == 0) {
|
||||
mainTextLabel = new Label(i18n.get("message.confirm.assign.consequences.none"));
|
||||
} else {
|
||||
mainTextLabel = new Label(i18n.get("message.confirm.assign.consequences.text", new Object[]{targetsCount}));
|
||||
}
|
||||
|
||||
layout.addComponent(mainTextLabel);
|
||||
|
||||
HorizontalLayout buttonsLayout = new HorizontalLayout();
|
||||
buttonsLayout.setSizeFull();
|
||||
buttonsLayout.setSpacing(true);
|
||||
buttonsLayout.addStyleName("actionButtonsMargin");
|
||||
layout.addComponent(buttonsLayout);
|
||||
|
||||
|
||||
okButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SAVE_BUTTON, i18n.get("button.ok"), "", "", true,
|
||||
FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class);
|
||||
okButton.setSizeUndefined();
|
||||
okButton.addStyleName("default-color");
|
||||
okButton.addClickListener(this);
|
||||
buttonsLayout.addComponent(okButton);
|
||||
buttonsLayout.setComponentAlignment(okButton, Alignment.MIDDLE_RIGHT);
|
||||
buttonsLayout.setExpandRatio(okButton, 1.0F);
|
||||
|
||||
|
||||
cancelButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_BUTTON, i18n.get("button.cancel"), "", "", true,
|
||||
FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class);
|
||||
cancelButton.setSizeUndefined();
|
||||
cancelButton.addStyleName("default-color");
|
||||
cancelButton.addClickListener(this);
|
||||
buttonsLayout.addComponent(cancelButton);
|
||||
buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT);
|
||||
buttonsLayout.setExpandRatio(cancelButton, 1.0F);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buttonClick(Button.ClickEvent event) {
|
||||
if(event.getButton().getId().equals(okButton.getId())) {
|
||||
callback.onConfirmResult(true);
|
||||
} else {
|
||||
callback.onConfirmResult(false);
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ConfirmCallback extends Serializable {
|
||||
void onConfirmResult(boolean accepted);
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||
import org.eclipse.hawkbit.ui.components.ProxyTargetFilter;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
@@ -85,7 +87,7 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery<ProxyTargetFilter>
|
||||
targetFilterQuery = getTargetFilterQueryManagement().findAllTargetFilterQuery(
|
||||
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort));
|
||||
} else {
|
||||
targetFilterQuery = getTargetFilterQueryManagement().findTargetFilterQueryByFilters(
|
||||
targetFilterQuery = getTargetFilterQueryManagement().findTargetFilterQueryByName(
|
||||
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort),
|
||||
searchText);
|
||||
}
|
||||
@@ -98,6 +100,11 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery<ProxyTargetFilter>
|
||||
proxyTarFilter.setModifiedDate(SPDateTimeUtil.getFormattedDate(tarFilterQuery.getLastModifiedAt()));
|
||||
proxyTarFilter.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(tarFilterQuery));
|
||||
proxyTarFilter.setQuery(tarFilterQuery.getQuery());
|
||||
|
||||
final DistributionSet distributionSet = tarFilterQuery.getAutoAssignDistributionSet();
|
||||
if (distributionSet != null) {
|
||||
proxyTarFilter.setAutoAssignDistributionSet(new ProxyDistribution(distributionSet));
|
||||
}
|
||||
proxyTargetFilter.add(proxyTarFilter);
|
||||
}
|
||||
return proxyTargetFilter;
|
||||
@@ -117,7 +124,7 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery<ProxyTargetFilter>
|
||||
.findAllTargetFilterQuery(new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort));
|
||||
} else {
|
||||
firstPageTargetFilter = getTargetFilterQueryManagement()
|
||||
.findTargetFilterQueryByFilters(new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort), searchText);
|
||||
.findTargetFilterQueryByName(new PageRequest(0, SPUIDefinitions.PAGE_SIZE, sort), searchText);
|
||||
}
|
||||
final long size = firstPageTargetFilter.getTotalElements();
|
||||
|
||||
|
||||
@@ -17,9 +17,15 @@ import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Link;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.UI;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
|
||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
|
||||
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
|
||||
@@ -43,15 +49,11 @@ import com.vaadin.data.Item;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Button.ClickEvent;
|
||||
import com.vaadin.ui.Link;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* Displays list of target filter queries
|
||||
*
|
||||
*/
|
||||
@SpringComponent
|
||||
@@ -75,6 +77,12 @@ public class TargetFilterTable extends Table {
|
||||
@Autowired
|
||||
private transient TargetFilterQueryManagement targetFilterQueryManagement;
|
||||
|
||||
@Autowired
|
||||
private transient DistributionSetManagement distributionSetManagement;
|
||||
|
||||
@Autowired
|
||||
private DistributionSetSelectWindow dsSelectWindow;
|
||||
|
||||
private Container container;
|
||||
|
||||
private static final int PROPERTY_DEPT = 3;
|
||||
@@ -141,15 +149,17 @@ public class TargetFilterTable extends Table {
|
||||
container.addContainerProperty(SPUILabelDefinitions.VAR_CREATED_DATE, Date.class, null);
|
||||
container.addContainerProperty(SPUILabelDefinitions.VAR_MODIFIED_DATE, Date.class, null);
|
||||
container.addContainerProperty(SPUILabelDefinitions.VAR_MODIFIED_BY, String.class, null);
|
||||
container.addContainerProperty(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET, String.class, null);
|
||||
}
|
||||
|
||||
private List<TableColumn> getVisbleColumns() {
|
||||
final List<TableColumn> columnList = new ArrayList<>();
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.NAME, i18n.get("header.name"), 0.2F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_USER, i18n.get("header.createdBy"), 0.15F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_USER, i18n.get("header.createdBy"), 0.1F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_DATE, i18n.get("header.createdDate"), 0.2F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_BY, i18n.get("header.modifiedBy"), 0.15F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_BY, i18n.get("header.modifiedBy"), 0.1F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.2F));
|
||||
columnList.add(new TableColumn(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET, i18n.get("header.auto.assignment.ds"), 0.1F));
|
||||
columnList.add(new TableColumn(SPUIDefinitions.CUSTOM_FILTER_DELETE, i18n.get("header.delete"), 0.1F));
|
||||
return columnList;
|
||||
|
||||
@@ -171,7 +181,7 @@ public class TargetFilterTable extends Table {
|
||||
return deleteIcon;
|
||||
}
|
||||
|
||||
private String getDeleteIconId(final String targetFilterName) {
|
||||
private static String getDeleteIconId(final String targetFilterName) {
|
||||
return new StringBuilder(UIComponentIdProvider.CUSTOM_FILTER_DELETE_ICON).append('.').append(targetFilterName)
|
||||
.toString();
|
||||
}
|
||||
@@ -207,6 +217,9 @@ public class TargetFilterTable extends Table {
|
||||
addGeneratedColumn(SPUILabelDefinitions.NAME,
|
||||
(source, itemId, columnId) -> customFilterDetailButton((Long) itemId));
|
||||
|
||||
addGeneratedColumn(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET,
|
||||
(source, itemId, columnId) -> customFilterDistributionSetButton((Long) itemId));
|
||||
|
||||
}
|
||||
|
||||
private Button customFilterDetailButton(final Long itemId) {
|
||||
@@ -221,6 +234,34 @@ public class TargetFilterTable extends Table {
|
||||
return updateIcon;
|
||||
}
|
||||
|
||||
private Button customFilterDistributionSetButton(final Long itemId) {
|
||||
final Item row1 = getItem(itemId);
|
||||
final ProxyDistribution distSet = (ProxyDistribution) row1.getItemProperty(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET).getValue();
|
||||
final String buttonId = "distSetButton";
|
||||
Button updateIcon;
|
||||
if(distSet == null) {
|
||||
updateIcon = SPUIComponentProvider.getButton(buttonId, i18n.get("button.no.auto.assignment"),
|
||||
i18n.get("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleSmallNoBorder.class);
|
||||
} else {
|
||||
updateIcon = SPUIComponentProvider.getButton(buttonId, distSet.getNameVersion(),
|
||||
i18n.get("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleSmallNoBorder.class);
|
||||
}
|
||||
|
||||
updateIcon.addClickListener(this::onClickOfDistributionSetButton);
|
||||
updateIcon.setData(row1);
|
||||
updateIcon.addStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link");
|
||||
|
||||
return updateIcon;
|
||||
}
|
||||
|
||||
private void onClickOfDistributionSetButton(final ClickEvent event) {
|
||||
final Item item = (Item) ((Button) event.getComponent()).getData();
|
||||
final Long tfqId = (Long)item.getItemProperty(SPUILabelDefinitions.VAR_ID).getValue();
|
||||
|
||||
dsSelectWindow.showForTargetFilter(tfqId);
|
||||
|
||||
}
|
||||
|
||||
private void onClickOfDetailButton(final ClickEvent event) {
|
||||
final String targetFilterName = (String) ((Button) event.getComponent()).getData();
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
|
||||
@@ -481,6 +481,11 @@ public final class SPUIDefinitions {
|
||||
*/
|
||||
public static final String FILTER_BY_INVALID_QUERY = "FilterByInvalidFilterQueryText";
|
||||
|
||||
/**
|
||||
* Filter by distribution set complete.
|
||||
*/
|
||||
public static final String FILTER_BY_DS_COMPLETE = "FilterByDistributionSetComplete";
|
||||
|
||||
/**
|
||||
* Sort order of column - created at in target table.
|
||||
*/
|
||||
|
||||
@@ -203,6 +203,10 @@ public final class SPUILabelDefinitions {
|
||||
* ASSIGNED DISTRIBUTION ID.
|
||||
*/
|
||||
public static final String ASSIGNED_DISTRIBUTION_ID = "assignedDistributionSet.id";
|
||||
/**
|
||||
* AUTO ASSIGN DISTRIBUTION SET ID
|
||||
*/
|
||||
public static final String AUTO_ASSIGN_DISTRIBUTION_SET = "autoAssignDistributionSet";
|
||||
/**
|
||||
* ASSIGNED DISTRIBUTION Name & Version.
|
||||
*/
|
||||
|
||||
@@ -877,6 +877,26 @@ public final class UIComponentIdProvider {
|
||||
*/
|
||||
public static final String DOWNLOAD_ANONYMOUS_CHECKBOX = "downloadanonymouscheckbox";
|
||||
|
||||
/**
|
||||
* Distribution set select table id
|
||||
*/
|
||||
public static final String DIST_SET_SELECT_TABLE_ID = "distribution.set.select.table";
|
||||
|
||||
/**
|
||||
* Distribution set select window id
|
||||
*/
|
||||
public static final String DIST_SET_SELECT_WINDOW_ID = "distribution.set.select.window";
|
||||
|
||||
/**
|
||||
* Distribution set select consequences window id
|
||||
*/
|
||||
public static final String DIST_SET_SELECT_CONS_WINDOW_ID = "distribution.set.select.consequences.window";
|
||||
|
||||
/**
|
||||
* Distribution set select enable checkbox id
|
||||
*/
|
||||
public static final String DIST_SET_SELECT_ENABLE_ID = "distribution.set.select.enable";
|
||||
|
||||
/**
|
||||
* /* Private Constructor.
|
||||
*/
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
|
||||
.v-table-cell-content {
|
||||
height: 27px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ button.no.actions = No actions
|
||||
button.ok = OK
|
||||
button.cancel = Cancel
|
||||
button.upload.file = Upload File
|
||||
button.no.auto.assignment = none
|
||||
button.auto.assignment.desc = Select auto assign distribution set
|
||||
bulk.targets.upload = Please upload csv file.
|
||||
bulkupload.ds.name = DS Name
|
||||
|
||||
@@ -59,6 +61,7 @@ caption.filter.simple = Simple Filter
|
||||
caption.filter.custom = Custom Filter
|
||||
caption.metadata = Metadata
|
||||
|
||||
caption.select.auto.assign.dist = Select auto assignment distribution set
|
||||
caption.add.softwaremodule = Configure Software Module
|
||||
caption.add.new.dist = Configure New Distribution
|
||||
caption.update.dist = Configure Update Distribution
|
||||
@@ -92,26 +95,27 @@ caption.confirm.abort.action = Confirm Abort Action
|
||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||
caption.metadata.popup = Metadata of
|
||||
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
|
||||
|
||||
caption.confirm.assign.consequences = Auto assign consequences
|
||||
caption.auto.assignment.ds = Auto assignment
|
||||
|
||||
# Labels prefix with - label
|
||||
label.dist.details.type = Type :
|
||||
label.dist.details.name = Name :
|
||||
label.dist.details.version = Version :
|
||||
label.dist.details.vendor = Vendor :
|
||||
label.dist.details.jvm = Runtime :
|
||||
label.dist.details.ah = Application :
|
||||
label.dist.details.os = OS :
|
||||
label.modified.date = Last modified at :
|
||||
label.modified.by = Last modified by :
|
||||
label.created.at = Created at :
|
||||
label.created.by = Created by :
|
||||
label.target.count = Targets :
|
||||
label.description = Description :
|
||||
label.ip = Address :
|
||||
label.type = Type :
|
||||
label.assigned.type = Assignment type :
|
||||
label.assigned.count = {0} Assigned
|
||||
label.dist.details.type = Type :
|
||||
label.dist.details.name = Name :
|
||||
label.dist.details.version = Version :
|
||||
label.dist.details.vendor = Vendor :
|
||||
label.dist.details.jvm = Runtime :
|
||||
label.dist.details.ah = Application :
|
||||
label.dist.details.os = OS :
|
||||
label.modified.date = Last modified at :
|
||||
label.modified.by = Last modified by :
|
||||
label.created.at = Created at :
|
||||
label.created.by = Created by :
|
||||
label.target.count = Targets :
|
||||
label.description = Description :
|
||||
label.ip = Address :
|
||||
label.type = Type :
|
||||
label.assigned.type = Assignment type :
|
||||
label.assigned.count = {0} Assigned
|
||||
label.installed.count = {0} Installed
|
||||
label.mandatory.field = * Mandatory Field
|
||||
label.components.drop.area = Drop here to delete
|
||||
@@ -133,10 +137,6 @@ label.target.filter.count = Total Targets:
|
||||
label.target.filtered.total = Total filtered targets :
|
||||
label.filter.selected = Selected:
|
||||
label.filter.shown = Shown:
|
||||
label.filter = Filter :
|
||||
label.target.filter.count = Total Targets :
|
||||
label.filter.selected = Selected :
|
||||
label.filter.shown = Shown :
|
||||
label.filter.targets = Filtered targets :
|
||||
label.filter.status = Status,
|
||||
label.filter.tags = Tags,
|
||||
@@ -155,9 +155,9 @@ label.cancelling = Canceling
|
||||
label.retrieved = Retrieved
|
||||
label.download = Downloading
|
||||
label.unknown = Unknown
|
||||
label.target.id = Controller Id :
|
||||
label.target.ip = Controller IP :
|
||||
label.target.security.token = Security token :
|
||||
label.target.id = Controller Id :
|
||||
label.target.ip = Controller IP :
|
||||
label.target.security.token = Security token :
|
||||
label.filter.by.status = Filter by Status
|
||||
label.target.controller.attrs = <b>Controller attributes</b>
|
||||
label.target.lastpolldate = Last poll :
|
||||
@@ -168,9 +168,11 @@ label.configuration.auth.gatewaytoken = Allow a gateway to authenticate and mana
|
||||
label.configuration.auth.targettoken = Allow targets to authenticate directly with their target security token
|
||||
label.configuration.anonymous.download = Allow targets to download artifacts without security credentials
|
||||
label.unsupported.browser.ie=Sorry! current browser is not supported. Please use Internet Explorer 11 and above
|
||||
label.auto.assign.description=When an auto assign distribution set is selected, it will be automatically assigned to all targets that match the target filter.
|
||||
label.auto.assign.enable=Enable auto assignment
|
||||
|
||||
# Checkbox label prefix with - checkbox
|
||||
checkbox.dist.migration.required = Required Migration Step :
|
||||
checkbox.dist.migration.required = Required Migration Step :
|
||||
checkbox.dist.required.migration.step = Required Migration Step
|
||||
|
||||
# TextFields prefix with - textfield
|
||||
@@ -186,7 +188,7 @@ prompt.target.id = Controller ID
|
||||
|
||||
|
||||
#Tooltips prefix with - tooltip
|
||||
tooltip.add.module = Add Software Module
|
||||
tooltip.add.module = Add Software Module
|
||||
tooltip.status.unknown = Unknown
|
||||
tooltip.status.registered = Registered
|
||||
tooltip.status.pending = Pending
|
||||
@@ -240,7 +242,7 @@ message.software.type.discard.success = All software moduleTypes selected for de
|
||||
message.assign.software.discard.success = All software moduleTypes selected for assign are discarded successfully !
|
||||
message.software.delete.success = All software modules selected for delete are deleted successfully !
|
||||
message.software.type.delete.success = All software modules types selected for delete are deleted successfully !
|
||||
message.dist.set.type.deleted.success = {0} DistributionSetType deleted successfully !
|
||||
message.dist.set.type.deleted.success = {0} DistributionSetType deleted successfully !
|
||||
message.new.dist.save.success = {0} - {1} saved successfully
|
||||
message.dist.update.success = {0} - {1} updated successfully
|
||||
message.duplicate.dist = Distribution set [{0}] or version [{1}] must be unique, entered value already exists.
|
||||
@@ -248,7 +250,7 @@ message.error.view = No such view: {0}
|
||||
message.accessdenied.view = No access to view: {0}
|
||||
message.no.data = No data available
|
||||
message.target.assignment = {0} Assignment(s) done
|
||||
message.target.deleted = {0} Target(s) deleted
|
||||
message.target.deleted = {0} Target(s) deleted
|
||||
message.dist.deleted = {0} Distribution set(s) deleted
|
||||
message.tag.update.mandatory = Please select the Tag to update
|
||||
message.tag.duplicate.check = {0} already exists, please enter another value
|
||||
@@ -274,7 +276,7 @@ message.error.ah.softmodule = Please select the Application to delete
|
||||
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||
message.cancel.action = Cancel..
|
||||
message.cancel.action.success = Action cancelled successfully !
|
||||
message.cancel.action.failed = Unable to cancel the action !
|
||||
message.cancel.action.failed = Unable to cancel the action !
|
||||
message.cancel.action.confirm = Are you sure that you want to cancel this action?
|
||||
message.target.alreadyAssigned = {0} Target(s) were already assigned
|
||||
message.dist.alreadyAssigned = {0} Distribution Set(s) were already assigned
|
||||
@@ -283,8 +285,8 @@ message.force.action.confirm = Are you sure that you want to force this action?
|
||||
message.force.action.success = Action forced successfully !
|
||||
message.forcequit.action = Force Quit..
|
||||
message.forcequit.action.success = Action has been force quit successfully !
|
||||
message.forcequit.action.failed = Force Quitting the action is not possible !
|
||||
message.forcequit.action.confirm = Attention!\nForce quit should only be used when the assignment action is not working properly.\nForce quitting an action has no effect on the connected target. It is just resetting \nthe data stored on the SP update server. \nAre you absolutely sure that you want to force quit this action?
|
||||
message.forcequit.action.failed = Force Quitting the action is not possible !
|
||||
message.forcequit.action.confirm = Attention!\nForce quit should only be used when the assignment action is not working properly.\nForce quitting an action has no effect on the connected target. It is just resetting \nthe data stored on the SP update server. \nAre you absolutely sure that you want to force quit this action?
|
||||
message.distribution.no.update = distribution {0} set is already assigned to targets and cannot be changed
|
||||
message.action.not.allowed = Action not allowed
|
||||
message.action.did.not.work = Action did not work. Please try again.
|
||||
@@ -306,12 +308,14 @@ message.update.filter.success = Custom filter updated Successfully!
|
||||
message.target.filter.validation = Please enter name and query
|
||||
message.target.filter.duplicate = {0} already exists, please enter another value
|
||||
message.tag.use.bulk.upload = {0} cannot be deleted .It is in use in targets bulk upload
|
||||
message.bulk.upload.tag.assignment.failed = Tag {0} assignment failed as tag no longer exists
|
||||
message.bulk.upload.tag.assignments.failed= Few tag assignments failed as tags no longer exists
|
||||
message.bulk.upload.tag.assignment.failed = Tag {0} assignment failed as tag no longer exists
|
||||
message.bulk.upload.tag.assignments.failed= Few tag assignments failed as tags no longer exists
|
||||
message.confirm.assign.consequences.none = This auto assignment will not have any effect on the currently available targets. In future added targets might match the filter and will receive the selected distribution set automatically.
|
||||
message.confirm.assign.consequences.text = When you confirm this auto assignment, {0} targets which match the filter will immediately get assigned with the selected distribution set.
|
||||
|
||||
# action info
|
||||
action.target.table.selectall = Select all (Ctrl+A)
|
||||
action.target.table.clear = Clear selections
|
||||
action.target.table.clear = Clear selections
|
||||
|
||||
#reused messages
|
||||
soft.module.jvm =Runtime
|
||||
@@ -322,8 +326,8 @@ soft.module.os =OS
|
||||
message.error.noFileSelected = No file selected for upload
|
||||
message.error.noProvidedName = Please provide custom file name
|
||||
message.error.noSwModuleSelected = Please select a Software Module
|
||||
message.no.duplicateFiles = Duplicate files selected
|
||||
message.no.duplicateFile = Duplicate file selected :
|
||||
message.no.duplicateFiles = Duplicate files selected
|
||||
message.no.duplicateFile = Duplicate file selected :
|
||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||
message.duplicate.filename = Duplicate file name
|
||||
message.swModule.deleted = {0} Software Module(s) deleted
|
||||
@@ -337,7 +341,7 @@ message.abort.upload = Are you sure that you want to abort the upload?
|
||||
|
||||
|
||||
upload.swModuleTable.header = Software Module
|
||||
upload.selectedfile.name = file selected for upload
|
||||
upload.selectedfile.name = file selected for upload
|
||||
upload.file.name = File name
|
||||
upload.sha1 = SHA1 checksum
|
||||
upload.md5 = MD5 checksum
|
||||
@@ -366,7 +370,6 @@ custom.created.date = Created Date
|
||||
|
||||
#Manage distributions view
|
||||
label.drop.dist.delete.area = Drop here<br>to delete
|
||||
label.no.tag.assigned = NO TAG
|
||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
||||
message.dist.inuse = {0} Distribution is already assigned to target
|
||||
@@ -376,9 +379,7 @@ message.target.assigned = {0} is assigned to {1}
|
||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||
message.dist.type.discard.success = All Distribution Types are discarded successfully !
|
||||
message.dist.discard.success = All Distributions are discarded successfully !
|
||||
message.assign.discard.success = All assignments are discarded successfully !
|
||||
message.target.ds.assign.success = Assignments saved successfully !
|
||||
message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists!
|
||||
message.key.missing = Key is missing !
|
||||
message.value.missing = Value is missing !
|
||||
@@ -449,12 +450,12 @@ header.assigned.ds = Assigned DS
|
||||
header.installed.ds = Installed DS
|
||||
header.target.status = Status
|
||||
header.target.tags = Tags
|
||||
header.distributionset = Distribution set
|
||||
header.numberofgroups = No. of groups
|
||||
header.detail.status = Detail status
|
||||
header.total.targets = Total targets
|
||||
header.total.targets = Total targets
|
||||
header.key = Key
|
||||
header.value = Value
|
||||
header.auto.assignment.ds = Auto assignment
|
||||
header.target.filter.name = Target filter name
|
||||
header.target.filter.query = Target filter query
|
||||
|
||||
distribution.details.header = Distribution set
|
||||
target.details.header = Target
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
|
||||
#########################################################################################
|
||||
# This is the messages_en.properties file
|
||||
#########################################################################################
|
||||
|
||||
# Button names prefix with - button
|
||||
button.save = Save
|
||||
button.delete = Delete
|
||||
button.discard = Discard
|
||||
button.discard.all = Discard All
|
||||
button.delete.all = Delete All
|
||||
button.assign.all = Save Assign
|
||||
button.actions = You have actions
|
||||
button.no.actions = No actions
|
||||
button.ok = OK
|
||||
button.cancel = Cancel
|
||||
button.upload.file = Upload File
|
||||
bulk.targets.upload = Please upload csv file.
|
||||
bulkupload.ds.name = DS Name
|
||||
|
||||
# Headers prefix with - header
|
||||
header.target.table=Targets
|
||||
header.dist.table=Distributions
|
||||
header.filter.tag=Filter by Tag
|
||||
header.target.filter.tag=Filters
|
||||
header.first.assignment.table = Targets
|
||||
header.second.assignment.table = Distributions
|
||||
header.dist.first.assignment.table = Distributions
|
||||
header.dist.second.assignment.table = Software Modules
|
||||
header.third.assignment.table = Discard
|
||||
header.one.deletedist.table = Distribution Name
|
||||
header.second.deletedist.table = Discard Changes
|
||||
header.first.deletetarget.table = Target Name
|
||||
header.second.deletetarget.table = Discard Changes
|
||||
header.first.deleteswmodule.table = Delete software
|
||||
header.first.delete.dist.type.table = DistributionSetType
|
||||
header.second.delete.dist.type.table = Discard
|
||||
header.first.delete.swmodule.type.table = Software Module Type
|
||||
header.second.delete.swmodule.type.table = Discard
|
||||
header.dist.twintable.selected=Selected
|
||||
header.dist.twintable.available=Available
|
||||
header.target.installed = Installed
|
||||
header.target.assigned = Assigned
|
||||
|
||||
# Captions prefix with - caption
|
||||
caption.action.history = Action history for {0}
|
||||
caption.error = Error
|
||||
caption.new.softwaremodule.application = Configure New Application
|
||||
caption.new.softwaremodule.jvm = Configure New Runtime
|
||||
caption.new.softwaremodule.os = Configure New OS
|
||||
caption.metadata = Metadata
|
||||
|
||||
|
||||
caption.add.softwaremodule = Configure Software Module
|
||||
caption.add.new.dist = Configure New Distribution
|
||||
caption.update.dist = Configure Update Distribution
|
||||
caption.add.tag = Configure Tag
|
||||
caption.add.type = Configure Type
|
||||
caption.add.new.target = Configure New Target
|
||||
caption.update.target = Configure Update Target
|
||||
caption.bulk.upload.targets = Bulk Upload
|
||||
caption.softwares.distdetail.tab = Modules
|
||||
caption.tags.tab = Tags
|
||||
caption.logs.tab = Logs
|
||||
caption.attributes.tab = Attributes
|
||||
caption.types.tab = Types
|
||||
caption.save.window = Action Details
|
||||
caption.assign.dist.accordion.tab = Assign Distribution Set
|
||||
caption.delete.dist.accordion.tab = Delete Distributions
|
||||
caption.delete.target.accordion.tab = Delete Targets
|
||||
caption.delete.swmodule.accordion.tab = Delete SW Modules
|
||||
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
||||
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
||||
caption.attributes = Attributes
|
||||
caption.panel.dist.installed = Installed Distribution Set
|
||||
caption.panel.dist.assigned = Assigned Distribution Set
|
||||
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
||||
caption.cancel.action.confirmbox = Confirm Action Cancellation
|
||||
caption.forced.datefield = Force update at time
|
||||
caption.force.action.confirmbox = Confirm Force Active Action
|
||||
caption.filter.simple = Simple Filter
|
||||
caption.filter.custom = Custom Filter
|
||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||
caption.confirm.abort.action = Confirm Abort Action
|
||||
|
||||
caption.metadata.popup = Metadata of
|
||||
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
|
||||
|
||||
# Labels prefix with - label
|
||||
label.dist.details.type = Type :
|
||||
label.dist.details.name = Name :
|
||||
label.dist.details.version = Version :
|
||||
label.dist.details.vendor = Vendor :
|
||||
label.dist.details.jvm = Runtime :
|
||||
label.dist.details.ah = Application :
|
||||
label.dist.details.os = OS :
|
||||
label.modified.date = Last modified at :
|
||||
label.modified.by = Last modified by :
|
||||
label.created.at = Created at :
|
||||
label.created.by = Created by :
|
||||
label.target.count = Targets :
|
||||
label.description = Description :
|
||||
label.ip = Address :
|
||||
label.type = Type :
|
||||
label.assigned.type = Assignment type :
|
||||
label.assigned.count = {0} Assigned
|
||||
label.installed.count = {0} Installed
|
||||
label.mandatory.field = * Mandatory Field
|
||||
label.components.drop.area = Drop here to delete
|
||||
label.software.module.drop.area = Delete Software
|
||||
label.create.tag = Create Tag
|
||||
label.update.tag = Update Tag
|
||||
label.create.type = Create Type
|
||||
label.update.type = Update Type
|
||||
label.singleAssign.type = Firmware (FW)
|
||||
label.multiAssign.type = Software (SW)
|
||||
label.choose.type = Choose Type
|
||||
label.choose.type.color = Choose Type Color
|
||||
label.combobox.type = Select Type
|
||||
label.combobox.tag = Select Tag
|
||||
label.choose.tag = Choose Tag to update
|
||||
label.choose.tag.color = Choose Tag Color
|
||||
label.filter = Filter:
|
||||
label.target.filter.count = Total Targets:
|
||||
label.target.filtered.total = Total filtered targets :
|
||||
label.filter.selected = Selected:
|
||||
label.filter.shown = Shown:
|
||||
label.filter = Filter :
|
||||
label.target.filter.count = Total Targets :
|
||||
label.filter.selected = Selected :
|
||||
label.filter.shown = Shown :
|
||||
label.filter.status = Status,
|
||||
label.filter.tags = Tags,
|
||||
label.filter.text = Search Text
|
||||
label.filter.dist = Distribution,
|
||||
label.filter.custom = Custom
|
||||
label.target.filter.truncated={0} targets has been truncated in the list due the target size limit of {1}, use filters to reduce the targets to be shown
|
||||
label.active =Active
|
||||
label.inactive = In-active
|
||||
label.finished = Finished
|
||||
label.error = Error
|
||||
label.warning = Warning
|
||||
label.running = Running
|
||||
label.cancelled = Cancelled
|
||||
label.cancelling = Canceling
|
||||
label.retrieved = Retrieved
|
||||
label.download = Downloading
|
||||
label.scheduled = Scheduled
|
||||
label.target.id = Controller Id :
|
||||
label.target.ip = Controller IP :
|
||||
label.target.security.token = Security token :
|
||||
label.filter.by.status = Filter by Status
|
||||
label.target.controller.attrs = <b>Controller attributes</b>
|
||||
label.target.lastpolldate = Last poll :
|
||||
label.no.tag.assigned = NO TAG
|
||||
label.tag.name = Tag name
|
||||
label.configuration.auth.header = Allow targets to authenticate via a certificate authenticated by an reverse proxy
|
||||
label.configuration.auth.gatewaytoken = Allow a gateway to authenticate and manage multiple targets through a gateway security token
|
||||
label.configuration.auth.targettoken = Allow targets to authenticate directly with their target security token
|
||||
label.configuration.anonymous.download = Allow targets to download artifacts without security credentials
|
||||
label.unsupported.browser.ie=Sorry! current browser is not supported. Please use Internet Explorer 11 and above
|
||||
|
||||
# Checkbox label prefix with - checkbox
|
||||
checkbox.dist.migration.required = Required Migration Step :
|
||||
checkbox.dist.required.migration.step = Required Migration Step
|
||||
|
||||
# TextFields prefix with - textfield
|
||||
textfield.name = Name
|
||||
textfield.key = Key
|
||||
textfield.version = Version
|
||||
textfield.vendor = Vendor
|
||||
textfield.description = Description
|
||||
textfield.customfiltername = Filter name
|
||||
textfield.value = Value
|
||||
ui.version = Powered by Bosch IoT Software Provisioning
|
||||
prompt.target.id = Controller ID
|
||||
|
||||
|
||||
#Tooltips prefix with - tooltip
|
||||
tooltip.add.module = Add Software Module
|
||||
tooltip.status.unknown = Unknown
|
||||
tooltip.status.registered = Registered
|
||||
tooltip.status.pending = Pending
|
||||
tooltip.status.error = Error
|
||||
tooltip.status.insync = In-sync
|
||||
tooltip.delete.module = Select and delete Software Module
|
||||
tooltip.forced.item=Forced update action
|
||||
tooltip.soft.item=Soft update action which interacts with an user as a attempt update action for example
|
||||
tooltip.timeforced.item=Soft update until a specific time and then the action will be forced
|
||||
tooltip.check.for.mandatory=Check to make Mandatory
|
||||
tooltip.artifact.icon=Show Artifact Details
|
||||
tooltip.click.to.edit = Click to edit
|
||||
tooltip.metadata.icon = Manage Metadata
|
||||
|
||||
|
||||
# Notification messages prefix with - message
|
||||
message.save.success = {0} saved successfully
|
||||
message.update.success = {0} updated successfully
|
||||
message.delete.success = {0} deleted successfully
|
||||
message.dist.installedorassigned = Target {targId} is already assigned/installed with distribution
|
||||
message.dist.pending.action = Target {0} is already assigned with distribution {1} . Pending for action
|
||||
message.empty.target.tags= No Tags Created
|
||||
message.empty.disttype.tags = No Distribution type tags created
|
||||
message.select.row = Please select a row to drag
|
||||
message.error = Unknown error occured during the operation. Please contact administrator
|
||||
message.dist.assigned.one = {0} is assigned to {1}
|
||||
message.dist.assigned.many = {0} DistributionSets are assigned to {1}
|
||||
message.dist.unassigned.one = {0} is unassigned from {1}
|
||||
message.dist.unassigned.many = {0} DistributionSets are unassigned from {1}
|
||||
message.target.assigned.one = {0} is assigned to {1}
|
||||
message.target.assigned.many = {0} Targets are assigned to {1}
|
||||
message.target.unassigned.one = {0} is unassigned from {1}
|
||||
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
||||
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
||||
message.cannot.delete = Cannot be deleted
|
||||
message.check.softwaremodule = Please provide both name and version!
|
||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||
message.duplicate.softwaremodule = {0} : {1} already exists!
|
||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||
message.tag.delete = Please unclick the tag {0}, then try to delete
|
||||
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
||||
message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete
|
||||
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
||||
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
||||
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
||||
message.dist.deleted.pending = Distribution(s) already deleted.Pending for action
|
||||
message.dist.delete.success = All selected distribution sets are deleted successfully !
|
||||
message.dist.discard.success = All distributions selected for delete are discarded successfully !
|
||||
message.target.delete.success = All selected targets are deleted successfully !
|
||||
message.target.discard.success = All targets selected for delete are discarded successfully !
|
||||
message.software.discard.success = All software modules selected for delete are discarded successfully !
|
||||
message.software.type.discard.success = All software moduleTypes selected for delete are discarded successfully !
|
||||
message.assign.software.discard.success = All software moduleTypes selected for assign are discarded successfully !
|
||||
message.software.delete.success = All software modules selected for delete are deleted successfully !
|
||||
message.software.type.delete.success = All software modules types selected for delete are deleted successfully !
|
||||
message.dist.set.type.deleted.success = {0} DistributionSetType deleted successfully !
|
||||
message.new.dist.save.success = {0} - {1} saved successfully
|
||||
message.dist.update.success = {0} - {1} updated successfully
|
||||
message.duplicate.dist = Distribution set [{0}] or version [{1}] must be unique, entered value already exists.
|
||||
message.error.view = No such view: {0}
|
||||
message.accessdenied.view = No access to view: {0}
|
||||
message.no.data = No data available
|
||||
message.target.assignment = {0} Assignment(s) done
|
||||
message.target.deleted = {0} Target(s) deleted
|
||||
message.dist.deleted = {0} Distribution Set(s) deleted
|
||||
message.tag.update.mandatory = Please select the Tag to update
|
||||
message.tag.duplicate.check = {0} already exists, please enter another value
|
||||
message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value
|
||||
message.type.key.swmodule.duplicate.check = Software Module type with key {0} already exists, please give another value
|
||||
message.no.action.history = No action history is available for the target : {0}
|
||||
message.no.available = --No messages available--
|
||||
message.no.actionupdateds.available = No other updates available for this action
|
||||
message.mandatory.check = Mandatory details are missing
|
||||
message.target.duplicate.check = Target [ {0} ] must be unique, entered value already exists.
|
||||
message.permission.insufficient = Insufficient permissions to perform this action.
|
||||
message.error.temp = The operation cannot be fulfilled due to {0}. Please contact administrator
|
||||
message.dist.alreadyassigned = {0} : {1} is already assigned/installed, cannot be updated
|
||||
message.dist.tag.alreadyassigned = {0} : {1} is already assigned/installed, cannot assign/un-assign to tag
|
||||
message.dists.unassign.tag.alreadyassigned = Few of the DistributionSet's are already assigned to Target, those cannot be unassigned from Tag"
|
||||
message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are already assigned to Target, those cannot be assigned to Tag"
|
||||
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
||||
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
||||
message.dist.no.operation = {0} - already assigned/installed, No operation
|
||||
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module?
|
||||
message.error.os.softmodule = Please select the OS to delete
|
||||
message.error.ah.softmodule = Please select the Application to delete
|
||||
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||
message.cancel.action = Cancel
|
||||
message.cancel.action.success = Action cancelled successfully !
|
||||
message.cancel.action.failed = Unable to cancel the action !
|
||||
message.cancel.action.confirm = Are you sure that you want to cancel this action?
|
||||
message.target.alreadyAssigned = {0} Target(s) were already assigned
|
||||
message.dist.alreadyAssigned = {0} Distribution Set(s) were already assigned
|
||||
message.force.action = Force
|
||||
message.force.action.confirm = Are you sure that you want to force this action?
|
||||
message.force.action.success = Action forced successfully !
|
||||
message.distribution.no.update = distribution {0} set is already assigned to targets and cannot be changed
|
||||
message.action.not.allowed = Action not allowed
|
||||
message.action.did.not.work = Action did not work. Please try again.
|
||||
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
||||
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
||||
message.error.missing.typename = Missing Type Name
|
||||
message.error.missing.typenameorkey = Missing Type Name or Key
|
||||
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
||||
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
||||
message.error.missing.tagname = Please select tag name
|
||||
message.type.delete = Please unclick the distribution type {0}, then try to delete
|
||||
message.error.dist.set.type.update= Distribution Set Type is already assigned to targets and cannot be changed
|
||||
message.target.ds.assign.success = Assignments saved successfully !
|
||||
message.no.directory.upload = Directory upload is not supported
|
||||
|
||||
message.delete.filter.confirm = Are you sure that you want to delete custom filter?
|
||||
message.delete.filter.success = Custom filter {0} deleted Successfully!
|
||||
message.create.filter.success = Custom filter {0} created Successfully!
|
||||
message.update.filter.success = Custom filter updated Successfully!
|
||||
message.target.filter.validation = Please enter name and query
|
||||
message.target.filter.duplicate = {0} already exists, please enter another value
|
||||
message.tag.use.bulk.upload = {0} cannot be deleted .It is in use in targets bulk upload
|
||||
message.bulk.upload.tag.assignment.failed = Tag {0} assignment failed as tag no longer exists
|
||||
message.bulk.upload.tag.assignments.failed= Few tag assignments failed as tags no longer exists
|
||||
|
||||
#reused messages
|
||||
soft.module.jvm =Runtime
|
||||
soft.module.application =Application
|
||||
soft.module.os =OS
|
||||
|
||||
#Artifact upload
|
||||
message.error.noFileSelected = No file selected for upload
|
||||
message.error.noProvidedName = Please provide custom file name
|
||||
message.error.noSwModuleSelected = Please select a Software Module
|
||||
message.no.duplicateFiles = Duplicate files selected
|
||||
message.no.duplicateFile = Duplicate file selected :
|
||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||
message.duplicate.filename = Duplicate file name
|
||||
message.swModule.deleted = {0} Software Module(s) deleted
|
||||
message.error.missing.tagname = Please select tag name
|
||||
message.upload.failed = Streaming Failed
|
||||
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
||||
message.uploadedfile.aborted = File upload aborted
|
||||
message.file.not.found = File not found
|
||||
message.artifact.deleted =Artifact with file {0} deleted successfully
|
||||
message.abort.upload = Are you sure that you want to abort the upload?
|
||||
|
||||
|
||||
|
||||
upload.swModuleTable.header = Software Module
|
||||
upload.selectedfile.name = file selected for upload
|
||||
upload.file.name = File name
|
||||
upload.sha1 = SHA1 checksum
|
||||
upload.md5 = MD5 checksum
|
||||
upload.last.modified.date=Last modified date
|
||||
upload.failed = Failed
|
||||
upload.success = Success
|
||||
upload.caption.add.new.swmodule = Configure New Software Module
|
||||
upload.caption.delete.swmodule = Configure Delete Software Module
|
||||
upload.swmodule.type = Type
|
||||
upload.artifact.alreadyExists = Artifact will be overridden as the given name already exists
|
||||
upload.size = Size(B)
|
||||
upload.validation = Validation
|
||||
upload.reason = Reason
|
||||
upload.action = Action
|
||||
upload.result.status = Upload status
|
||||
upload.file = Upload File
|
||||
upload.caption.update.swmodule = Update Software Module
|
||||
caption.tab.details = Details
|
||||
caption.tab.description = Description
|
||||
|
||||
caption.delete.artifact.confirmbox = Confirm Artifact Delete Action
|
||||
|
||||
#Manage distributions view
|
||||
label.drop.dist.delete.area = Drop here<br>to delete
|
||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||
message.software.assignment = {0} Assignment(s) done
|
||||
message.dist.inuse = {0} Distribution is already assigned to target
|
||||
message.software.dist.already.assigned = {0} Distribution already has Software Module {1}
|
||||
message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1}
|
||||
message.target.assigned = {0} is assigned to {1}
|
||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||
message.dist.type.discard.success = All Distribution Types are discarded successfully !
|
||||
message.dist.discard.success = All Distributions are discarded successfully !
|
||||
message.assign.discard.success = All assignments are discarded successfully !
|
||||
message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists!
|
||||
message.key.missing = Key is missing !
|
||||
message.value.missing = Value is missing !
|
||||
message.metadata.saved = Metadata with key {0} successfully saved !
|
||||
message.metadata.updated = Metadata with key {0} successfully updated !
|
||||
message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value
|
||||
message.metadata.deleted.successfully = Metadata with key {0} successfully deleted !
|
||||
message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ?
|
||||
message.error.notification.ds.target.assigned = Distribution set {0}:{1} is already assigned to targets and cannot be changed
|
||||
|
||||
|
||||
# Login view
|
||||
notification.login.title=Welcome to Bosch IoT Software Provisioning.
|
||||
notification.login.description=Please login with your Bosch Identity Management credentials.
|
||||
notification.login.failed.title=Login failed!
|
||||
notification.login.failed.description=Login with the given credentials failed.
|
||||
notification.login.failed.credentialsexpired.title=Passwort Abgelaufen!
|
||||
notification.login.failed.credentialsexpired.description=Passwort ist entweder abgelaufen or muss initial gesetzt werden, bitte im Benutzer Verwaltungssystem <20>ndern.
|
||||
label.login.tenant=Tenant
|
||||
label.login.username=Username
|
||||
label.login.password=Password
|
||||
button.login.signin=Sign in
|
||||
checkbox.login.rememberme=Remember me
|
||||
|
||||
# Links
|
||||
link.documentation.name=Dokumentation
|
||||
link.demo.name=Demo
|
||||
link.requestaccount.name=Beantragung eines Accounts
|
||||
link.support.name=Support
|
||||
link.usermanagement.name=Benutzerverwaltung
|
||||
|
||||
|
||||
# System Configuration View
|
||||
notification.configuration.save=Ver<EFBFBD>nderungen gespeichert
|
||||
configuration.defaultdistributionset.title=Distribution Set Typ
|
||||
configuration.defaultdistributionset.select.label=Wahl des default Distribution Set typs:
|
||||
configuration.savebutton.tooltip=Konfigurationen speichern
|
||||
configuration.cancellbutton.tooltip=Konfigurationen zur<75>cksetzen
|
||||
configuration.authentication.title=Authentifikationseinstellungen
|
||||
|
||||
#Calendar
|
||||
calendar.year=Jahr
|
||||
calendar.years=Jahre
|
||||
calendar.month=Monat
|
||||
calendar.months=Monate
|
||||
calendar.day=Tag
|
||||
calendar.days=Tage
|
||||
calendar.hour=Stunde
|
||||
calendar.hours=Stunden
|
||||
calendar.minute=Minute
|
||||
calendar.minutes=Minuten
|
||||
calendar.second=Sekunde
|
||||
calendar.seconds=Sekunden
|
||||
|
||||
header.name = Name
|
||||
header.vendor = Vendor
|
||||
header.version = Version
|
||||
header.description = Description
|
||||
header.createdBy = Created By
|
||||
header.createdDate = Created Date
|
||||
header.modifiedBy = Modified By
|
||||
header.modifiedDate = Modified Date
|
||||
header.delete = Delete
|
||||
header.assigned.ds = Assigned DS
|
||||
header.installed.ds = Installed DS
|
||||
header.status = Status
|
||||
header.target.tags = Tags
|
||||
header.distributionset = Distribution set
|
||||
header.numberofgroups = No. of groups
|
||||
header.detail.status = Detail status
|
||||
header.total.targets = Total targets
|
||||
header.type = Type
|
||||
header.swmodules = SwModules
|
||||
header.migrations.step=IsRequiredMigrationStep
|
||||
|
||||
header.action=Actions
|
||||
header.action.run=Run
|
||||
header.action.pause=Pause
|
||||
header.action.update=Edit
|
||||
|
||||
header.rolloutgroup.installed.percentage = % Finished
|
||||
header.rolloutgroup.threshold.error = Error threshold
|
||||
header.rolloutgroup.threshold = Trigger threshold
|
||||
|
||||
header.rolloutgroup.target.date = Date and time
|
||||
header.rolloutgroup.target.message = Messages
|
||||
|
||||
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
||||
|
||||
distribution.details.header = Distribution Set
|
||||
target.details.header = Target
|
||||
header.caption.mandatory = Mandatory
|
||||
header.caption.typename = SoftwareModuleType
|
||||
header.caption.softwaremodule = SoftwareModule
|
||||
header.caption.unassign = Unassign
|
||||
message.sw.unassigned = Software Module {0} successfully unassigned
|
||||
header.caption.upload.details = Upload details
|
||||
header.key = Key
|
||||
header.value = Value
|
||||
combo.type.tag.name = Type tag name
|
||||
|
||||
label.yes = Yes
|
||||
label.no =No
|
||||
|
||||
|
||||
#Menu
|
||||
menu.title = Software Provisioning
|
||||
|
||||
|
||||
#Rollout management
|
||||
prompt.number.of.groups = Number of groups
|
||||
prompt.tigger.threshold = Trigger threshold
|
||||
prompt.error.threshold = Error threshold
|
||||
prompt.distribution.set = Distribution Set
|
||||
caption.configure.rollout = Configure Rollout
|
||||
caption.update.rollout = Update Rollout
|
||||
prompt.target.filter = Custom Target Filter
|
||||
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
||||
message.rollout.max.group.number = Number of groups must not be greater than 500
|
||||
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
||||
message.rollout.field.value.range = Value should be in range {0} to {1}
|
||||
message.correct.invalid.value = Please correct invalid values
|
||||
message.enter.number = Please enter number
|
||||
message.rollout.started = Rollout {0} started successfully
|
||||
message.rollout.paused = Rollout {0} paused successfully
|
||||
message.rollout.resumed = Rollout {0} resumed successfully
|
||||
message.rollout.noofgroups.or.targetfilter.missing = Please enter number of groups and select target filter
|
||||
message.rollouts = Rollouts
|
||||
label.target.per.group = Targets per group :
|
||||
message.dist.already.assigned = Distribution {0} is already assigned to target
|
||||
message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator
|
||||
message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator
|
||||
|
||||
#Target Filter Management
|
||||
breadcrumb.target.filter.custom.filters = Custom Filters
|
||||
@@ -1,501 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
|
||||
#########################################################################################
|
||||
# This is the messages_en.properties file
|
||||
#########################################################################################
|
||||
|
||||
# Button names prefix with - button
|
||||
button.save = Save
|
||||
button.delete = Delete
|
||||
button.discard = Discard
|
||||
button.discard.all = Discard All
|
||||
button.delete.all = Delete All
|
||||
button.assign.all = Save Assign
|
||||
button.actions = You have actions
|
||||
button.no.actions = No actions
|
||||
button.ok = OK
|
||||
button.cancel = Cancel
|
||||
button.upload.file = Upload File
|
||||
bulk.targets.upload = Please upload csv file.
|
||||
bulkupload.ds.name = DS Name
|
||||
|
||||
# Headers prefix with - header
|
||||
header.target.table=Targets
|
||||
header.dist.table=Distributions
|
||||
header.filter.tag=Filter by Tag
|
||||
header.target.filter.tag=Filters
|
||||
header.first.assignment.table = Targets
|
||||
header.second.assignment.table = Distributions
|
||||
header.dist.first.assignment.table = Distributions
|
||||
header.dist.second.assignment.table = Software Modules
|
||||
header.third.assignment.table = Discard
|
||||
header.one.deletedist.table = Distribution Name
|
||||
header.second.deletedist.table = Discard Changes
|
||||
header.first.deletetarget.table = Target Name
|
||||
header.second.deletetarget.table = Discard Changes
|
||||
header.first.deleteswmodule.table = Delete software
|
||||
header.first.delete.dist.type.table = DistributionSetType
|
||||
header.second.delete.dist.type.table = Discard
|
||||
header.first.delete.swmodule.type.table = Software Module Type
|
||||
header.second.delete.swmodule.type.table = Discard
|
||||
header.dist.twintable.selected=Selected
|
||||
header.dist.twintable.available=Available
|
||||
header.target.installed = Installed
|
||||
header.target.assigned = Assigned
|
||||
|
||||
# Captions prefix with - caption
|
||||
caption.action.history = Action history for {0}
|
||||
caption.error = Error
|
||||
caption.new.softwaremodule.application = Configure New Application
|
||||
caption.new.softwaremodule.jvm = Configure New Runtime
|
||||
caption.new.softwaremodule.os = Configure New OS
|
||||
caption.filter.simple = Simple Filter
|
||||
caption.filter.custom = Custom Filter
|
||||
caption.metadata = Metadata
|
||||
|
||||
caption.add.softwaremodule = Configure Software Module
|
||||
caption.add.new.dist = Configure New Distribution
|
||||
caption.update.dist = Configure Update Distribution
|
||||
caption.add.tag = Configure Tag
|
||||
caption.add.type = Configure Type
|
||||
caption.add.new.target = Configure New Target
|
||||
caption.update.target = Configure Update Target
|
||||
caption.bulk.upload.targets = Bulk Upload
|
||||
caption.softwares.distdetail.tab = Modules
|
||||
caption.tags.tab = Tags
|
||||
caption.logs.tab = Logs
|
||||
caption.attributes.tab = Attributes
|
||||
caption.types.tab = Types
|
||||
caption.save.window = Action Details
|
||||
caption.assign.dist.accordion.tab = Assign Software Module
|
||||
caption.delete.dist.accordion.tab = Delete Distributions
|
||||
caption.delete.target.accordion.tab = Delete Targets
|
||||
caption.delete.swmodule.accordion.tab = Delete SW Modules
|
||||
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
||||
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
||||
caption.attributes = Attributes
|
||||
caption.panel.dist.installed = Installed Distribution Set
|
||||
caption.panel.dist.assigned = Assigned Distribution Set
|
||||
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
||||
caption.cancel.action.confirmbox = Confirm Action Cancellation
|
||||
caption.forced.datefield = Force update at time
|
||||
caption.force.action.confirmbox = Confirm Force Active Action
|
||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||
caption.metadata.popup = Metadata of
|
||||
caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action
|
||||
|
||||
caption.confirm.abort.action = Confirm Abort Action
|
||||
|
||||
# Labels prefix with - label
|
||||
label.dist.details.type = Type :
|
||||
label.dist.details.name = Name :
|
||||
label.dist.details.version = Version :
|
||||
label.dist.details.vendor = Vendor :
|
||||
label.dist.details.jvm = Runtime :
|
||||
label.dist.details.ah = Application :
|
||||
label.dist.details.os = OS :
|
||||
label.modified.date = Last modified at :
|
||||
label.modified.by = Last modified by :
|
||||
label.created.at = Created at :
|
||||
label.created.by = Created by :
|
||||
label.target.count = Targets :
|
||||
label.description = Description :
|
||||
label.ip = Address :
|
||||
label.type = Type :
|
||||
label.assigned.type = Assignment type :
|
||||
label.assigned.count = {0} Assigned
|
||||
label.installed.count = {0} Installed
|
||||
label.mandatory.field = * Mandatory Field
|
||||
label.components.drop.area = Drop here to delete
|
||||
label.software.module.drop.area = Delete Software
|
||||
label.create.tag = Create Tag
|
||||
label.update.tag = Update Tag
|
||||
label.create.type = Create Type
|
||||
label.update.type = Update Type
|
||||
label.singleAssign.type = Firmware (FW)
|
||||
label.multiAssign.type = Software (SW)
|
||||
label.choose.type = Choose Type to Update
|
||||
label.choose.type.color = Choose Type Color
|
||||
label.combobox.type = Select Type
|
||||
label.combobox.tag = Select Tag
|
||||
label.choose.tag = Choose Tag to update
|
||||
label.choose.tag.color = Choose Tag Color
|
||||
label.filter = Filter:
|
||||
label.target.filter.count = Total Targets:
|
||||
label.target.filtered.total = Total filtered targets :
|
||||
label.filter.selected = Selected:
|
||||
label.filter.shown = Shown:
|
||||
label.filter.targets = Filtered targets :
|
||||
label.filter = Filter :
|
||||
label.target.filter.count = Total Targets :
|
||||
label.filter.selected = Selected :
|
||||
label.filter.shown = Shown :
|
||||
label.filter.status = Status,
|
||||
label.filter.tags = Tags,
|
||||
label.filter.text = Search Text
|
||||
label.filter.dist = Distribution,
|
||||
label.filter.custom = Custom
|
||||
label.target.filter.truncated={0} targets has been truncated in the list due the target size limit of {1}, use filters to reduce the targets to be shown
|
||||
label.active =Active
|
||||
label.inactive = In-active
|
||||
label.finished = Finished
|
||||
label.error = Error
|
||||
label.warning = Warning
|
||||
label.running = Running
|
||||
label.cancelled = Cancelled
|
||||
label.cancelling = Canceling
|
||||
label.retrieved = Retrieved
|
||||
label.download = Downloading
|
||||
label.scheduled = Scheduled
|
||||
label.target.id = Controller Id :
|
||||
label.target.ip = Controller IP :
|
||||
label.target.security.token = Security token :
|
||||
label.filter.by.status = Filter by Status
|
||||
label.target.controller.attrs = <b>Controller attributes</b>
|
||||
label.target.lastpolldate = Last poll :
|
||||
label.no.tag.assigned = NO TAG
|
||||
label.tag.name = Tag name
|
||||
label.configuration.auth.header = Allow targets to authenticate via a certificate authenticated by an reverse proxy
|
||||
label.configuration.auth.gatewaytoken = Allow a gateway to authenticate and manage multiple targets through a gateway security token
|
||||
label.configuration.auth.targettoken = Allow targets to authenticate directly with their target security token
|
||||
label.configuration.anonymous.download = Allow targets to download artifacts without security credentials
|
||||
label.unsupported.browser.ie=Sorry! current browser is not supported. Please use Internet Explorer 11 and above
|
||||
|
||||
# Checkbox label prefix with - checkbox
|
||||
checkbox.dist.migration.required = Required Migration Step :
|
||||
checkbox.dist.required.migration.step = Required Migration Step
|
||||
|
||||
# TextFields prefix with - textfield
|
||||
textfield.name = Name
|
||||
textfield.key = Key
|
||||
textfield.version = Version
|
||||
textfield.vendor = Vendor
|
||||
textfield.description = Description
|
||||
textfield.customfiltername = Filter name
|
||||
textfield.value = Value
|
||||
ui.version = Powered by Bosch IoT Software Provisioning
|
||||
prompt.target.id = Controller ID
|
||||
|
||||
|
||||
#Tooltips prefix with - tooltip
|
||||
tooltip.add.module = Add Software Module
|
||||
tooltip.status.unknown = Unknown
|
||||
tooltip.status.registered = Registered
|
||||
tooltip.status.pending = Pending
|
||||
tooltip.status.error = Error
|
||||
tooltip.status.insync = In-sync
|
||||
tooltip.delete.module = Select and delete Software Module
|
||||
tooltip.forced.item=Forced update action
|
||||
tooltip.soft.item=Soft update action which interacts with an user as a attempt update action for example
|
||||
tooltip.timeforced.item=Soft update until a specific time and then the action will be forced
|
||||
tooltip.check.for.mandatory=Check to make Mandatory
|
||||
tooltip.artifact.icon=Show Artifact Details
|
||||
tooltip.click.to.edit = Click to edit
|
||||
tooltip.metadata.icon = Manage Metadata
|
||||
|
||||
|
||||
# Notification messages prefix with - message
|
||||
message.save.success = {0} saved successfully
|
||||
message.update.success = {0} updated successfully
|
||||
message.delete.success = {0} deleted successfully
|
||||
message.dist.installedorassigned = Target {targId} is already assigned/installed with distribution
|
||||
message.dist.pending.action = Target {0} is already assigned with distribution {1} . Pending for action
|
||||
message.empty.target.tags= No Tags Created
|
||||
message.empty.disttype.tags = No Distribution type tags created
|
||||
message.select.row = Please select a row to drag
|
||||
message.error = Unknown error occured during the operation. Please contact administrator
|
||||
message.dist.assigned.one = {0} is assigned to {1}
|
||||
message.dist.assigned.many = {0} DistributionSets are assigned to {1}
|
||||
message.dist.unassigned.one = {0} is unassigned from {1}
|
||||
message.dist.unassigned.many = {0} DistributionSets are unassigned from {1}
|
||||
message.target.assigned.one = {0} is assigned to {1}
|
||||
message.target.assigned.many = {0} Targets are assigned to {1}
|
||||
message.target.unassigned.one = {0} is unassigned from {1}
|
||||
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
||||
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
||||
message.cannot.delete = Cannot be deleted
|
||||
message.check.softwaremodule = Please provide both name and version!
|
||||
message.duplicate.softwaremodule = {0} : {1} already exists!
|
||||
message.tag.delete = Please unclick the tag {0}, then try to delete
|
||||
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
||||
message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete
|
||||
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
||||
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
||||
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
||||
message.dist.deleted.pending = Distribution(s) already deleted.Pending for action
|
||||
message.dist.delete.success = All selected distribution sets are deleted successfully !
|
||||
message.dist.discard.success = All distributions selected for delete are discarded successfully !
|
||||
message.target.delete.success = All selected targets are deleted successfully !
|
||||
message.target.discard.success = All targets selected for delete are discarded successfully !
|
||||
message.software.discard.success = All software modules selected for delete are discarded successfully !
|
||||
message.software.type.discard.success = All software moduleTypes selected for delete are discarded successfully !
|
||||
message.assign.software.discard.success = All software moduleTypes selected for assign are discarded successfully !
|
||||
message.software.delete.success = All software modules selected for delete are deleted successfully !
|
||||
message.software.type.delete.success = All software modules types selected for delete are deleted successfully !
|
||||
message.dist.set.type.deleted.success = {0} DistributionSetType deleted successfully !
|
||||
message.new.dist.save.success = {0} - {1} saved successfully
|
||||
message.dist.update.success = {0} - {1} updated successfully
|
||||
message.duplicate.dist = Distribution set [{0}] or version [{1}] must be unique, entered value already exists.
|
||||
message.error.view = No such view: {0}
|
||||
message.accessdenied.view = No access to view: {0}
|
||||
message.no.data = No data available
|
||||
message.target.assignment = {0} Assignment(s) done
|
||||
message.target.deleted = {0} Target(s) deleted
|
||||
message.dist.deleted = {0} Distribution set(s) deleted
|
||||
message.tag.update.mandatory = Please select the Tag to update
|
||||
message.tag.duplicate.check = {0} already exists, please enter another value
|
||||
message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value
|
||||
message.type.key.swmodule.duplicate.check = Software Module type with key {0} already exists, please give another value
|
||||
message.no.action.history = No action history is available for the target : {0}
|
||||
message.no.available = --No messages available--
|
||||
message.no.actionupdateds.available = No other updates available for this action
|
||||
message.mandatory.check = Mandatory details are missing
|
||||
message.target.duplicate.check = Target [ {0} ] must be unique, entered value already exists.
|
||||
message.permission.insufficient = Insufficient permissions to perform this action.
|
||||
message.error.temp = The operation cannot be fulfilled due to {0}. Please contact administrator
|
||||
message.dist.alreadyassigned = {0} : {1} is already assigned/installed, cannot be updated
|
||||
message.dist.tag.alreadyassigned = {0} : {1} is already assigned/installed, cannot assign/un-assign to tag
|
||||
message.dists.unassign.tag.alreadyassigned = Few of the DistributionSet's are already assigned to Target, those cannot be unassigned from Tag"
|
||||
message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are already assigned to Target, those cannot be assigned to Tag"
|
||||
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
||||
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
||||
message.dist.no.operation = {0} - already assigned/installed, No operation
|
||||
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module?
|
||||
message.error.os.softmodule = Please select the OS to delete
|
||||
message.error.ah.softmodule = Please select the Application to delete
|
||||
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||
message.cancel.action = Cancel
|
||||
message.cancel.action.success = Action cancelled successfully !
|
||||
message.cancel.action.failed = Unable to cancel the action !
|
||||
message.cancel.action.confirm = Are you sure that you want to cancel this action?
|
||||
message.target.alreadyAssigned = {0} Target(s) were already assigned
|
||||
message.dist.alreadyAssigned = {0} Distribution Set(s) were already assigned
|
||||
message.force.action = Force
|
||||
message.force.action.confirm = Are you sure that you want to force this action?
|
||||
message.force.action.success = Action forced successfully !
|
||||
message.distribution.no.update = distribution {0} set is already assigned to targets and cannot be changed
|
||||
message.action.not.allowed = Action not allowed
|
||||
message.action.did.not.work = Action did not work. Please try again.
|
||||
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
||||
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
||||
message.error.missing.typename = Missing Type Name
|
||||
message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type
|
||||
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
||||
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
||||
message.error.missing.tagname = Please select tag name
|
||||
message.type.delete = Please unclick the distribution type {0}, then try to delete
|
||||
message.error.dist.set.type.update= Distribution Set Type is already assigned to targets and cannot be changed
|
||||
message.target.ds.assign.success = Assignments saved successfully !
|
||||
message.no.directory.upload = Directory upload is not supported
|
||||
|
||||
message.delete.filter.confirm = Are you sure that you want to delete custom filter?
|
||||
message.delete.filter.success = Custom filter {0} deleted Successfully!
|
||||
message.create.filter.success = Custom filter {0} created Successfully!
|
||||
message.update.filter.success = Custom filter updated Successfully!
|
||||
message.target.filter.validation = Please enter name and query
|
||||
message.target.filter.duplicate = {0} already exists, please enter another value
|
||||
|
||||
# action info
|
||||
action.target.table.selectall = Select all (Ctrl+A)
|
||||
action.target.table.clear = Clear selections
|
||||
|
||||
#reused messages
|
||||
soft.module.jvm =Runtime
|
||||
soft.module.application =Application
|
||||
soft.module.os =OS
|
||||
|
||||
#Artifact upload
|
||||
message.error.noFileSelected = No file selected for upload
|
||||
message.error.noProvidedName = Please provide custom file name
|
||||
message.error.noSwModuleSelected = Please select a Software Module
|
||||
message.no.duplicateFiles = Duplicate files selected
|
||||
message.no.duplicateFile = Duplicate file selected :
|
||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||
message.duplicate.filename = Duplicate file name
|
||||
message.swModule.deleted = {0} Software Module(s) deleted
|
||||
message.upload.failed = Streaming Failed
|
||||
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
||||
message.uploadedfile.aborted = File upload aborted
|
||||
message.file.not.found = File not found
|
||||
message.abort.upload = Are you sure that you want to abort the upload?
|
||||
|
||||
|
||||
upload.swModuleTable.header = Software Module
|
||||
upload.selectedfile.name = file selected for upload
|
||||
upload.file.name = File name
|
||||
upload.sha1 = SHA1 checksum
|
||||
upload.md5 = MD5 checksum
|
||||
upload.last.modified.date=Last modified date
|
||||
upload.failed = Failed
|
||||
upload.success = Success
|
||||
upload.caption.add.new.swmodule = Configure New Software Module
|
||||
upload.caption.delete.swmodule = Configure Delete Software Module
|
||||
upload.swmodule.type = Type
|
||||
upload.artifact.alreadyExists = Artifact will be overridden as the given name already exists
|
||||
upload.size = Size(B)
|
||||
upload.validation = Validation
|
||||
upload.reason = Reason
|
||||
upload.action = Action
|
||||
upload.result.status = Upload status
|
||||
upload.file = Upload File
|
||||
upload.caption.update.swmodule = Update Software Module
|
||||
caption.tab.details = Details
|
||||
caption.tab.description = Description
|
||||
|
||||
caption.delete.artifact.confirmbox = Confirm Artifact Delete Action
|
||||
|
||||
|
||||
#Manage distributions view
|
||||
label.drop.dist.delete.area = Drop here<br>to delete
|
||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
||||
message.dist.inuse = {0} Distribution is already assigned to target
|
||||
message.software.dist.already.assigned = {0} Distribution already has Software Module {1}
|
||||
message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1}
|
||||
message.target.assigned = {0} is assigned to {1}
|
||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||
message.dist.type.discard.success = All Distribution Types are discarded successfully !
|
||||
message.dist.discard.success = All Distributions are discarded successfully !
|
||||
message.assign.discard.success = All assignments are discarded successfully !
|
||||
message.key.missing = Key is missing !
|
||||
message.value.missing = Value is missing !
|
||||
message.metadata.saved = Metadata with key {0} successfully saved !
|
||||
message.metadata.updated = Metadata with key {0} successfully updated !
|
||||
message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value
|
||||
message.metadata.deleted.successfully = Metadata with key {0} successfully deleted !
|
||||
message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ?
|
||||
message.error.notification.ds.target.assigned = Distribution set {0}:{1} is already assigned to targets and cannot be changed
|
||||
|
||||
# Login view
|
||||
notification.login.title=Welcome to Bosch IoT Software Provisioning.
|
||||
notification.login.description=Please login with your Bosch Identity Management credentials.
|
||||
notification.login.failed.title=Login failed!
|
||||
notification.login.failed.description=Login with the given credentials failed.
|
||||
notification.login.failed.credentialsexpired.title=Password Expired!
|
||||
notification.login.failed.credentialsexpired.description=Password has been expired or needs to be set initially, please visit the User Management to change or set your password.
|
||||
label.login.tenant=Tenant
|
||||
label.login.username=Username
|
||||
label.login.password=Password
|
||||
button.login.signin=Sign in
|
||||
checkbox.login.rememberme=Remember me
|
||||
|
||||
# Links
|
||||
link.documentation.name=Documentation
|
||||
link.demo.name=Demo
|
||||
link.requestaccount.name=Request Account
|
||||
link.support.name=Support
|
||||
link.usermanagement.name=User Management
|
||||
|
||||
# System Configuration View
|
||||
notification.configuration.save=Saved changes
|
||||
configuration.defaultdistributionset.title=Distribution Set Type
|
||||
configuration.defaultdistributionset.select.label=Select the default Distribution Set type:
|
||||
configuration.savebutton.tooltip=Save Configurations
|
||||
configuration.cancellbutton.tooltip=Cancel Configurations
|
||||
configuration.authentication.title=Authentication Configuration
|
||||
controller.polling.title=Polling Configuration
|
||||
controller.polling.time=Polling Time
|
||||
controller.polling.overduetime=Polling Overdue Time
|
||||
|
||||
#Calendar
|
||||
calendar.year=year
|
||||
calendar.years=years
|
||||
calendar.month=month
|
||||
calendar.months=months
|
||||
calendar.day=day
|
||||
calendar.days=days
|
||||
calendar.hour=hour
|
||||
calendar.hours=hours
|
||||
calendar.minute=minute
|
||||
calendar.minutes=minutes
|
||||
calendar.second=second
|
||||
calendar.seconds=seconds
|
||||
|
||||
header.name = Name
|
||||
header.vendor = Vendor
|
||||
header.version = Version
|
||||
header.description = Description
|
||||
header.createdBy = Created By
|
||||
header.createdDate = Created Date
|
||||
header.modifiedBy = Modified By
|
||||
header.modifiedDate = Modified Date
|
||||
header.delete = Delete
|
||||
header.assigned.ds = Assigned DS
|
||||
header.installed.ds = Installed DS
|
||||
header.status = Status
|
||||
header.target.tags = Tags
|
||||
header.distributionset = Distribution Set
|
||||
header.numberofgroups = No. of groups
|
||||
header.detail.status = Detail status
|
||||
header.total.targets = Total targets
|
||||
header.type = Type
|
||||
header.swmodules = SwModules
|
||||
header.migrations.step=IsRequiredMigrationStep
|
||||
|
||||
header.action=Actions
|
||||
header.action.run=Run
|
||||
header.action.pause=Pause
|
||||
header.action.update=Edit
|
||||
|
||||
header.rolloutgroup.installed.percentage = % Finished
|
||||
header.rolloutgroup.threshold.error = Error threshold
|
||||
header.rolloutgroup.threshold = Trigger threshold
|
||||
|
||||
|
||||
|
||||
header.rolloutgroup.target.date = Date and time
|
||||
header.rolloutgroup.target.message = Messages
|
||||
|
||||
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
||||
|
||||
distribution.details.header = Distribution Set
|
||||
target.details.header = Target
|
||||
header.caption.mandatory = Mandatory
|
||||
header.caption.typename = SoftwareModuleType
|
||||
header.caption.softwaremodule = SoftwareModule
|
||||
header.caption.upload.details = Upload details
|
||||
header.key = Key
|
||||
header.value = Value
|
||||
combo.type.tag.name = Type tag name
|
||||
|
||||
label.yes = Yes
|
||||
label.no =No
|
||||
|
||||
#Menu
|
||||
menu.title = Software Provisioning
|
||||
|
||||
|
||||
#Rollout management
|
||||
prompt.number.of.groups = Number of groups
|
||||
prompt.tigger.threshold = Trigger threshold
|
||||
prompt.error.threshold = Error threshold
|
||||
prompt.distribution.set = Distribution Set
|
||||
caption.configure.rollout = Configure Rollout
|
||||
caption.update.rollout = Update Rollout
|
||||
prompt.target.filter = Custom Target Filter
|
||||
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
||||
message.rollout.max.group.number = Number of groups must not be greater than 500
|
||||
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
||||
message.correct.invalid.value = Please correct invalid values
|
||||
message.enter.number = Please enter number
|
||||
message.rollout.field.value.range = Value should be in range {0} to {1}
|
||||
message.rollout.started = Rollout {0} started successfully
|
||||
message.rollout.paused = Rollout {0} paused successfully
|
||||
message.rollout.resumed = Rollout {0} resumed successfully
|
||||
message.rollout.noofgroups.or.targetfilter.missing = Please enter number of groups and select target filter
|
||||
message.rollouts = Rollouts
|
||||
label.target.per.group = Targets per group :
|
||||
message.dist.already.assigned = Distribution {0} is already assigned to target
|
||||
message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator
|
||||
message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator
|
||||
|
||||
#Target Filter Management
|
||||
breadcrumb.target.filter.custom.filters = Custom Filters
|
||||
Reference in New Issue
Block a user