Merge branch 'master' into

MECS-1277_clearing_the_search_field_should_keep_the_focus

Conflicts:
	hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java
This commit is contained in:
venu1278
2016-02-15 15:51:19 +05:30
115 changed files with 5033 additions and 3529 deletions

View File

@@ -10,15 +10,31 @@ Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=svg)](htt
* You can also check out our [Project Homepage](https://projects.eclipse.org/projects/iot.hawkbit) for further contact options.
# Compile
```
mvn install
```
# Run and use
# Compile, Run and Getting Started
We are not providing an off the shelf installation ready hawkBit update server. However, we recommend to check out the [Example Application](examples/hawkbit-example-app) for a runtime ready Spring Boot based update server that is empowered by hawkBit.
#### Clone and build hawkBit
```
$ git clone https://github.com/eclipse/hawkbit.git
$ mvn clean install
```
#### Start hawkBit example app
[Example Application](examples/hawkbit-example-app)
```
$ java jar ./examples/hawkbit-example-app/target/hawkbit-example-app-#version#.jar
```
#### Start hawkBit device simulator
[Device Simulator](examples/hawkbit-device-simulator)
```
$ java jar ./examples/hawkbit-device-simulator/target/hawkbit-device-simulator-#version#.jar
```
#### Generate Getting Started data
[Example Management API Client](examples/hawkbit-mgmt-api-client)
```
$ java jar ./examples/hawkbit-mgmt-api-client/target/hawkbit-mgmt-api-client-#version#.jar
```
# Releases and Roadmap
* We are currently working on the first formal release under the Eclipse banner: 0.1 (see [Release 0.1 branch](https://github.com/eclipse/hawkbit/tree/release-train-0.1)).
@@ -29,11 +45,10 @@ We are not providing an off the shelf installation ready hawkBit update server.
* And of course tons of usability improvements and bug fixes.
## Try out examples
#### Standalone Test Application Server
[Example Application](examples/hawkbit-example-app)
#### Device Simulator using the DMF AMQP API
[Device Simulator](examples/hawkbit-device-simulator)
# Device Integration
There are two device integration APIs provided by the hawkbit update server.
* [Direct Device Integration API (HTTP)](DDIA.md)
* [Device Management Federation API (AMQP)](DMFA.md)
# Modules
`hawkbit-core` : core elements.
@@ -49,9 +64,3 @@ We are not providing an off the shelf installation ready hawkBit update server.
`hawkbit-rest-resource` : HTTP REST endpoints for the Management and the Direct Device API.
`hawkbit-ui` : Vaadin UI.
`hawkbit-cache-redis` : spring cache manager configuration and implementation with redis, distributed cache and distributed events.
# Device Integration
There are two device integration APIs provided by the hawkbit update server.
* [Direct Device Integration API (HTTP)](DDIA.md)
* [Device Management Federation API (AMQP)](DMFA.md)

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.simulator;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.hawkbit.simulator.DeviceSimulatorUpdater.UpdaterCallback;
import org.eclipse.hawkbit.simulator.http.ControllerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,28 +81,27 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice {
final String deploymentJson = controllerResource.getDeployment(getTenant(), getId(), actionId);
final String swVersion = JsonPath.parse(deploymentJson).read("deployment.chunks[0].version");
currentActionId = actionId;
deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, new UpdaterCallback() {
@Override
public void updateFinished(final AbstractSimulatedDevice device, final Long actionId) {
switch (device.getResponseStatus()) {
case SUCCESSFUL:
controllerResource.postSuccessFeedback(getTenant(), getId(), actionId);
break;
case ERROR:
controllerResource.postErrorFeedback(getTenant(), getId(), actionId);
break;
default:
throw new IllegalStateException("simulated device has an unknown response status + "
+ device.getResponseStatus());
}
currentActionId = null;
deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, (device, actionId1) -> {
switch (device.getResponseStatus()) {
case SUCCESSFUL:
controllerResource.postSuccessFeedback(getTenant(), getId(),
actionId1);
break;
case ERROR:
controllerResource.postErrorFeedback(getTenant(), getId(),
actionId1);
break;
default:
throw new IllegalStateException(
"simulated device has an unknown response status + " + device.getResponseStatus());
}
currentActionId = null;
});
}
} catch (final PathNotFoundException e) {
// href might not be in the json response, so ignore
// exception here.
LOGGER.trace("Response does not contain a deploymentbase href link, ignoring.");
LOGGER.trace("Response does not contain a deploymentbase href link, ignoring.", e);
}
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.simulator;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -41,7 +42,7 @@ public class DeviceSimulatorUpdater {
/**
* Starting an simulated update process of an simulated device.
*
*
* @param tenant
* the tenant of the device
* @param id
@@ -66,7 +67,7 @@ public class DeviceSimulatorUpdater {
}
private static final class DeviceSimulatorUpdateThread implements Runnable {
private static final Random rndSleep = new Random();
private static final Random rndSleep = new SecureRandom();
private final AbstractSimulatedDevice device;
private final SpSenderService spSenderService;
@@ -74,9 +75,8 @@ public class DeviceSimulatorUpdater {
private final EventBus eventbus;
private final UpdaterCallback callback;
private DeviceSimulatorUpdateThread(final AbstractSimulatedDevice device,
final SpSenderService spSenderService, final long actionId, final EventBus eventbus,
final UpdaterCallback callback) {
private DeviceSimulatorUpdateThread(final AbstractSimulatedDevice device, final SpSenderService spSenderService,
final long actionId, final EventBus eventbus, final UpdaterCallback callback) {
this.device = device;
this.spSenderService = spSenderService;
this.actionId = actionId;
@@ -89,8 +89,9 @@ public class DeviceSimulatorUpdater {
final double newProgress = device.getProgress() + 0.2;
device.setProgress(newProgress);
if (newProgress < 1.0) {
threadPool.schedule(new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus,
callback), rndSleep.nextInt(3000), TimeUnit.MILLISECONDS);
threadPool.schedule(
new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback),
rndSleep.nextInt(3000), TimeUnit.MILLISECONDS);
} else {
callback.updateFinished(device, actionId);
}
@@ -102,7 +103,7 @@ public class DeviceSimulatorUpdater {
* Callback interface which is called when the simulated update process has
* been finished and the caller of starting the simulated update process can
* send the result to the hawkbit update server back.
*
*
* @author Michael Hirsch
*
*/
@@ -111,7 +112,7 @@ public class DeviceSimulatorUpdater {
/**
* Callback method to indicate that the simulated update process has
* been finished.
*
*
* @param device
* the device which has been updated
* @param actionId

View File

@@ -16,6 +16,8 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -24,13 +26,15 @@ import com.google.common.eventbus.EventBus;
/**
* Poll time trigger which executes the {@link DDISimulatedDevice#poll()} every
* second.
*
*
* @author Michael Hirsch
*
*/
@Component
public class NextPollTimeController {
private static final Logger LOGGER = LoggerFactory.getLogger(NextPollTimeController.class);
private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
private static final ExecutorService pollService = Executors.newFixedThreadPool(1);
@@ -58,14 +62,9 @@ public class NextPollTimeController {
if (nextCounter < 0) {
if (device instanceof DDISimulatedDevice) {
try {
pollService.submit(new Runnable() {
@Override
public void run() {
((DDISimulatedDevice) device).poll();
}
});
} catch (final Exception e) {
pollService.submit(() -> ((DDISimulatedDevice) device).poll());
} catch (final IllegalStateException e) {
LOGGER.trace("Device could not be polled", e);
}
nextCounter = ((DDISimulatedDevice) device).getPollDelaySec();
}

View File

@@ -1,3 +1,39 @@
# HawkBit management API example
Example client that shows how to efficiently use the hawkBit management API.
Powered by [Feign](https://github.com/Netflix/feign).
Powered by [Feign](https://github.com/Netflix/feign).
## How to run the example client
Run getting started example
$ java -jar hawkbit-mgmt-api-client-#version#.jar
Run create and start rollout example
$ java -jar hawkbit-mgmt-api-client-#version#.jar --createrollout
## This example shows
In getting started example:
* creating software modules type
* creating distribution set type
* creating distribution sets
* creating software modules
* assigning software modules to distribution sets
In rollout mode:
* creating software modules type
* creating distribution set type
* creating distribution sets
* creating software modules
* assigning software modules to distribution sets
* creating a rollout
* starting a rollout

View File

@@ -16,9 +16,43 @@
<artifactId>hawkbit-examples-parent</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<artifactId>hawkbit-mgmt-api-client</artifactId>
<name>hawkBit Management API example client</name>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<outputDirectory>${baseDir}</outputDirectory>
<addResources>false</addResources>
<mainClass>org.eclipse.hawkbit.mgmt.client.Application</mainClass>
<layout>JAR</layout>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
@@ -26,45 +60,32 @@
<artifactId>hawkbit-rest-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-jackson</artifactId>
<version>8.12.1</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId>
<version>8.12.1</version>
<!-- need to overwrite for the interface inheritance feature of feign-core -->
<version>8.14.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-example-app</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<artifactId>hibernate-validator</artifactId>
<groupId>org.hibernate</groupId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>ru.yandex.qatools.allure</groupId>
<artifactId>allure-junit-adaptor</artifactId>
<scope>test</scope>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert-core</artifactId>
<scope>test</scope>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<scope>test</scope>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0-rc2</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,38 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import feign.Headers;
import feign.RequestLine;
/**
* Client binding for the Distribution resource of the management API.
*/
@FunctionalInterface
public interface DistributionSetResource {
/**
* Creates a list of distribution sets.
*
* @param sets
* the request body java bean containing the necessary attributes
* for creating a distribution set.
* @return the list of targets which have been created
*/
@RequestLine("POST " + RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
@Headers("Content-Type: application/json")
DistributionSetsRest createDistributionSets(final List<DistributionSetRequestBodyPost> sets);
}

View File

@@ -1,138 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
/**
* Client binding for the DistributionSetTag resource of the management API.
*/
public interface DistrubutionSetTagResource {
/**
* Retrieves a single distributionset tag based on the given ID.
*
* @param dsTagId
* the ID of the distributionset tag to retrieve
* @return a deserialized java bean containing the attributes of the
* returned distributionset tag
*/
@RequestLine("GET " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}")
TagRest getDistributionSetTag(@Param("dsTagId") Long dsTagId);
/**
* Creates a list of distributionset tags.
*
* @param tags
* the tags to be created
* @return the created tag list
*/
@RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING)
@Headers("Content-Type: application/json")
TagsRest createDistributionSetTags(List<TagRequestBodyPut> tags);
/**
* Update attributes of a distributionset tag.
*
* @param dsTagId
* the distributionset tag id to be updated
* @param tag
* the request body
* @return the updated distributionset tag
*/
@RequestLine("PUT " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}")
@Headers("Content-Type: application/json")
TagRest updateDistributionSetTag(@Param("dsTagId") Long dsTagId, TagRequestBodyPut tag);
/**
* Deletes given distributionset tag on given ID.
*
* @param dsTagId
* to be deleted
*/
@RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}")
void deleteDistributionSetTag(@Param("dsTagId") final Long dsTagId);
/**
* Retrieves a all assigned targets on the given distributionset tag id.
*
* @param dsTagId
* the ID of the distributionset tag to retrieve
* @return a list of targets
*/
@RequestLine("GET " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING
+ RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
DistributionSetsRest getAssignedDistributionSets(@Param("dsTagId") final Long dsTagId);
/**
* Toggle the tag assignment all assigned targets will be unassigned and all
* unassigned targets will be assigned.
*
* @param dsTagId
* the ID of the distributionset tag to toggle
* @param assignedTargetRequestBodies
* a list of controller ids
* @return a list of assigned and unassigned targets
*/
@RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING
+ RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + "/toggleTagAssignment")
@Headers("Content-Type: application/json")
DistributionSetTagAssigmentResultRest toggleTagAssignment(@Param("dsTagId") final Long dsTagId,
final List<AssignedDistributionSetRequestBody> assignedTargetRequestBodies);
/**
* Assign targets to a given distributionset tag id.
*
* @param dsTagId
* the ID of the distributionset tag to add the targets
* @param assignedTargetRequestBodies
* a list of controller ids
* @return a list of assigned targets
*/
@RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING
+ RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
@Headers("Content-Type: application/json")
TargetsRest assignDistributionSets(@Param("dsTagId") final Long dsTagId,
final List<AssignedDistributionSetRequestBody> assignedTargetRequestBodies);
/**
* Unassign targets to a given distributionset tag id.
*
* @param dsTagId
* the ID of the distributionset tag to add the targets
*/
@RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING
+ RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
void unassignDistributionSets(@Param("dsTagId") final Long dsTagId);
/**
* Unassign one target to a given distributionset tag id.
*
* @param dsTagId
* the ID of the distributionset tag to add the targets param
* @param dsId
* the distributionset id
*/
@RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING
+ RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + "/{dsId}")
void unassignDistributionSet(@Param("dsTagId") final Long dsTagId, @Param("dsId") final Long dsId);
}

View File

@@ -1,80 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
/**
* Client binding for the Target resource of the management API.
*/
public interface TargetResource {
/**
* Retrieves a single target based on the given ID.
*
* @param targetId
* the ID of the target to retrieve
* @return a deserialized java bean containing the attributes of the
* returned target
*/
@RequestLine("GET /rest/v1/targets/{targetId}")
TargetRest getTarget(@Param("targetId") final String targetId);
/**
* Paged query of targets resource.
*
* @param pagingOffsetParam
* of the paged query
* @param pagingLimitParam
* of the paged query
* @return paged list of target entries
*/
@RequestLine("GET /rest/v1/targets?offset={pagingOffsetParam}&limit={pagingLimitParam}")
TargetPagedList getTargets(@Param("pagingOffsetParam") int pagingOffsetParam,
@Param("pagingLimitParam") int pagingLimitParam);
/**
* Paged query of targets resource with default offset and limit.
*
* @return paged list of target entries
*/
@RequestLine("GET /rest/v1/targets")
TargetPagedList getTargets();
/**
* Deletes given target based on given ID.
*
* @param targetId
* to be deleted
*/
@RequestLine("DELETE /rest/v1/targets/{targetId}")
void deleteTarget(@Param("targetId") final String targetId);
/**
* Creates a list of targets.
*
* @param targets
* the request body java bean containing the necessary attributes
* for creating a target.
* @return the list of targets which have been created
*/
@RequestLine("POST /rest/v1/targets/")
@Headers("Content-Type: application/json")
TargetsRest createTargets(List<TargetRequestBody> targets);
}

View File

@@ -1,137 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
import feign.Headers;
import feign.Param;
import feign.RequestLine;
/**
* Client binding for the Target resource of the management API.
*/
public interface TargetTagResource {
/**
* Retrieves a single target tag based on the given ID.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @return a deserialized java bean containing the attributes of the
* returned target tag
*/
@RequestLine("GET " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}")
TagRest getTargetTag(@Param("targetTagId") Long targetTagId);
/**
* Creates a list of target tags.
*
* @param tags
* the tags to be created
* @return the created tag list
*/
@RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING)
@Headers("Content-Type: application/json")
TagsRest createTargetTag(List<TagRequestBodyPut> tags);
/**
* Update attributes of a target tag.
*
* @param targetTagId
* the target tag id to be updated
* @param tag
* the request body
* @return the updated target tag
*/
@RequestLine("PUT " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}")
@Headers("Content-Type: application/json")
TagRest updateTagretTag(@Param("targetTagId") Long targetTagId, TagRequestBodyPut tag);
/**
* Deletes given target tag on given ID.
*
* @param targetTagId
* to be deleted
*/
@RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}")
void deleteTargetTag(@Param("targetTagId") final Long targetTagId);
/**
* Retrieves a all assigned targets on the given target tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @return a list of targets
*/
@RequestLine("GET " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING
+ RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
TargetsRest getAssignedTargets(@Param("targetTagId") final Long targetTagId);
/**
* Toggle the tag assignment all assigned targets will be unassigned and all
* unassigned targets will be assigned.
*
* @param targetTagId
* the ID of the target tag to toggle
* @param assignedTargetRequestBodies
* a list of controller ids
* @return a list of assigned and unassigned targets
*/
@RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING
+ RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/toggleTagAssignment")
@Headers("Content-Type: application/json")
TargetTagAssigmentResultRest toggleTagAssignment(@Param("targetTagId") final Long targetTagId,
final List<AssignedTargetRequestBody> assignedTargetRequestBodies);
/**
* Assign targets to a given target tag id.
*
* @param targetTagId
* the ID of the target tag to add the targets
* @param assignedTargetRequestBodies
* a list of controller ids
* @return a list of assigned targets
*/
@RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING
+ RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
@Headers("Content-Type: application/json")
TargetsRest assignTargets(@Param("targetTagId") final Long targetTagId,
final List<AssignedTargetRequestBody> assignedTargetRequestBodies);
/**
* Unassign targets to a given target tag id.
*
* @param targetTagId
* the ID of the target tag to add the targets
*/
@RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING
+ RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
void unassignTargets(@Param("targetTagId") final Long targetTagId);
/**
* Unassign one target to a given target tag id.
*
* @param targetTagId
* the ID of the target tag to add the targets param
* @param controllerId
* the controller id
*/
@RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING
+ RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/{controllerId}")
void unassignTarget(@Param("targetTagId") final Long targetTagId, @Param("controllerId") final String controllerId);
}

View File

@@ -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.mgmt.client;
import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample;
import org.eclipse.hawkbit.mgmt.client.scenarios.GettingStartedDefaultScenario;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import feign.Contract;
import feign.auth.BasicAuthRequestInterceptor;
@SpringBootApplication
@EnableFeignClients
@EnableConfigurationProperties(ClientConfigurationProperties.class)
public class Application implements CommandLineRunner {
@Autowired
private ClientConfigurationProperties configuration;
@Autowired
private GettingStartedDefaultScenario gettingStarted;
@Autowired
private CreateStartedRolloutExample gettingStartedRolloutScenario;
public static void main(final String[] args) {
new SpringApplicationBuilder().showBanner(false).sources(Application.class).run(args);
}
@Override
public void run(final String... args) throws Exception {
if (containsArg("--createrollout", args)) {
// run the create and start rollout example
gettingStartedRolloutScenario.run();
} else {
// run the getting started scenario which creates a setup of
// distribution set and software modules to be used
gettingStarted.run();
}
}
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor(configuration.getUsername(), configuration.getPassword());
}
@Bean
public ApplicationJsonRequestHeaderInterceptor jsonHeaderInterceptor() {
return new ApplicationJsonRequestHeaderInterceptor();
}
@Bean
public Contract feignContract() {
return new IgnoreMultipleConsumersProducersSpringMvcContract();
}
private boolean containsArg(final String containsArg, final String... args) {
for (final String arg : args) {
if (arg.equalsIgnoreCase(containsArg)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,28 @@
/**
* 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.client;
import org.springframework.http.MediaType;
import feign.RequestInterceptor;
import feign.RequestTemplate;
/**
* An feign request interceptor to set the defined {@code Accept} and
* {@code Content-Type} headers for each request to {@code application/json}.
*/
public class ApplicationJsonRequestHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(final RequestTemplate template) {
template.header("Accept", MediaType.APPLICATION_JSON_VALUE);
template.header("Content-Type", MediaType.APPLICATION_JSON_VALUE);
}
}

View File

@@ -0,0 +1,49 @@
/**
* 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.client;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration bean which holds the configuration of the client e.g. the base
* URL of the hawkbit-server and the credentials to use the RESTful Management
* API.
*/
@ConfigurationProperties(prefix = "hawkbit")
public class ClientConfigurationProperties {
private String url = "localhost:8080";
private String username = "admin";
private String password = "admin"; // NOSONAR this password is only used for
// examples
public String getUrl() {
return url;
}
public void setUrl(final String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(final String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
}

View File

@@ -0,0 +1,43 @@
/**
* 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.client;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
import feign.MethodMetadata;
/**
* Own implementation of the {@link SpringMvcContract} which catches the
* {@link IllegalStateException} which occurs due multiple produces and consumes
* values in the request-mapping
* annoation.https://github.com/spring-cloud/spring-cloud-netflix/issues/808
*/
public class IgnoreMultipleConsumersProducersSpringMvcContract extends SpringMvcContract {
private static final Logger LOGGER = LoggerFactory
.getLogger(IgnoreMultipleConsumersProducersSpringMvcContract.class);
@Override
protected void processAnnotationOnMethod(final MethodMetadata data, final Annotation methodAnnotation,
final Method method) {
try {
super.processAnnotationOnMethod(data, methodAnnotation, method);
} catch (final IllegalStateException e) {
// ignore illegalstateexception here because it's thrown because of
// multiple consumers and produces, see
// https://github.com/spring-cloud/spring-cloud-netflix/issues/808
LOGGER.trace(e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the DistributionSet resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsets")
public interface DistributionSetResourceClient extends DistributionSetRestApi {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the DistributionSetTag resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettags")
public interface DistributionSetTagResourceClient extends DistributionSetTagRestApi {
}

View File

@@ -0,0 +1,21 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the DistributionSetType resource of the management API.
*
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettypes")
public interface DistributionSetTypeResourceClient extends DistributionSetTypeRestApi {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the Rollout resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/rollouts")
public interface RolloutResourceClient extends RolloutRestApi {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the SoftwareModule resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremodules")
public interface SoftwareModuleResourceClient extends SoftwareModuleRestAPI {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the oftwareModuleType resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremoduletypes")
public interface SoftwareModuleTypeResourceClient extends SoftwareModuleTypeRestApi {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.TargetRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the Target resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targets")
public interface TargetResourceClient extends TargetRestApi {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.client.resource;
import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi;
import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the TargetTag resource of the management API.
*/
@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targettags")
public interface TargetTagResourceClient extends TargetTagRestApi {
}

View File

@@ -0,0 +1,99 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost;
import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link DistributionSetRequestBodyPost}.
*
* @author Jonathan Knoblauch
*
*/
public class DistributionSetBuilder {
private String name;
private String version;
private String type;
/**
* @param name
* the name of the distribution set
* @return the builder itself
*/
public DistributionSetBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param version
* the version of the distribution set
* @return the builder itself
*/
public DistributionSetBuilder version(final String version) {
this.version = version;
return this;
}
/**
* @param type
* the distribution set type name for this distribution set
* @return the builder itself
*/
public DistributionSetBuilder type(final String type) {
this.type = type;
return this;
}
/**
* Builds a list with a single entry of
* {@link DistributionSetRequestBodyPost} which can directly be used to post
* on the RESTful-API.
*
* @return a single entry list of {@link DistributionSetRequestBodyPost}
*/
public List<DistributionSetRequestBodyPost> build() {
return Lists.newArrayList(doBuild(name));
}
/**
* Builds a list of multiple {@link DistributionSetRequestBodyPost} to
* create multiple distribution sets at once. An increasing number will be
* added to the name of the distribution set. The version and type will
* remain the same.
*
* @param count
* the amount of distribution sets body which should be created
* @return a list of {@link DistributionSetRequestBodyPost}
*/
public List<DistributionSetRequestBodyPost> buildAsList(final int count) {
final ArrayList<DistributionSetRequestBodyPost> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(name + index));
}
return bodyList;
}
private DistributionSetRequestBodyPost doBuild(final String prefixName) {
final DistributionSetRequestBodyPost body = new DistributionSetRequestBodyPost();
body.setName(prefixName);
body.setVersion(version);
body.setType(type);
return body;
}
}

View File

@@ -0,0 +1,124 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeAssigmentRest;
import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link DistributionSetTypeRequestBodyPost}.
*
* @author Jonathan Knoblauch
*
*/
public class DistributionSetTypeBuilder {
private String key;
private String name;
private final List<SoftwareModuleTypeAssigmentRest> mandatorymodules = Lists.newArrayList();
private final List<SoftwareModuleTypeAssigmentRest> optionalmodules = Lists.newArrayList();
/**
* @param key
* the key of the distribution set type
* @return the builder itself
*/
public DistributionSetTypeBuilder key(final String key) {
this.key = key;
return this;
}
/**
* @param name
* the name of the distribution set type
* @return the builder itself
*/
public DistributionSetTypeBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param softwareModuleTypeIds
* the IDs of the software module types which should be mandatory
* for the distribution set type
* @return the builder itself
*/
public DistributionSetTypeBuilder mandatorymodules(final Long... softwareModuleTypeIds) {
for (final Long id : softwareModuleTypeIds) {
final SoftwareModuleTypeAssigmentRest softwareModuleTypeAssigmentRest = new SoftwareModuleTypeAssigmentRest();
softwareModuleTypeAssigmentRest.setId(id);
this.mandatorymodules.add(softwareModuleTypeAssigmentRest);
}
return this;
}
/**
*
* @param softwareModuleTypeIds
* the IDs of the software module types which should be optional
* for the distribution set type
* @return the builder itself
*/
public DistributionSetTypeBuilder optionalmodules(final Long... softwareModuleTypeIds) {
for (final Long id : softwareModuleTypeIds) {
final SoftwareModuleTypeAssigmentRest softwareModuleTypeAssigmentRest = new SoftwareModuleTypeAssigmentRest();
softwareModuleTypeAssigmentRest.setId(id);
this.optionalmodules.add(softwareModuleTypeAssigmentRest);
}
return this;
}
/**
* Builds a list with a single entry of
* {@link DistributionSetTypeRequestBodyPost} which can directly be used in
* the RESTful-API.
*
* @return a single entry list of {@link DistributionSetTypeRequestBodyPost}
*/
public List<DistributionSetTypeRequestBodyPost> build() {
return Lists.newArrayList(doBuild(name, key));
}
/**
* Builds a list of multiple {@link DistributionSetTypeRequestBodyPost} to
* create multiple distribution set types at once. An increasing number will
* be added to the name and key of the distribution set type. The optional
* and mandatory software module types will remain the same.
*
* @param count
* the amount of distribution sets type body which should be
* created
* @return a list of {@link DistributionSetTypeRequestBodyPost}
*/
public List<DistributionSetTypeRequestBodyPost> buildAsList(final int count) {
final ArrayList<DistributionSetTypeRequestBodyPost> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(name + index, key + index));
}
return bodyList;
}
private DistributionSetTypeRequestBodyPost doBuild(final String prefixName, final String prefixKey) {
final DistributionSetTypeRequestBodyPost body = new DistributionSetTypeRequestBodyPost();
body.setKey(prefixKey);
body.setName(prefixName);
body.setMandatorymodules(mandatorymodules);
body.setOptionalmodules(optionalmodules);
return body;
}
}

View File

@@ -0,0 +1,115 @@
/**
* 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.client.resource.builder;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition.Condition;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody;
/**
*
* Builder pattern for building {@link RolloutRestRequestBody}.
*
* @author Jonathan Knoblauch
*
*/
public class RolloutBuilder {
private String name;
private int groupSize;
private String targetFilterQuery;
private long distributionSetId;
private String successThreshold;
private String errorThreshold;
/**
* @param name
* the name of the rollout
* @return the builder itself
*/
public RolloutBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param groupSize
* the amount of groups the rollout should be split into
* @return the builder itself
*/
public RolloutBuilder groupSize(final int groupSize) {
this.groupSize = groupSize;
return this;
}
/**
* @param targetFilterQuery
* the FIQL query language to filter targets to contain in the
* rollout
* @return the builder itself
*/
public RolloutBuilder targetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
return this;
}
/**
* @param distributionSetId
* the ID of the distribution set to assign to the target in the
* rollout
* @return the builder itself
*/
public RolloutBuilder distributionSetId(final long distributionSetId) {
this.distributionSetId = distributionSetId;
return this;
}
/**
* @param successThreshold
* the threshold to be used to indicate if a deployment group is
* successful, to trigger the success action
* @return the builder itself
*/
public RolloutBuilder successThreshold(final String successThreshold) {
this.successThreshold = successThreshold;
return this;
}
/**
* @param errorThreshold
* the threshold to be used to indicate if a deployment group is
* failing, to trigger the error action
* @return the builder itself
*/
public RolloutBuilder errorThreshold(final String errorThreshold) {
this.errorThreshold = errorThreshold;
return this;
}
/**
* Builds the rollout rest body to creating a rollout.
*
* @return the rest request body for creating a rollout
*/
public RolloutRestRequestBody build() {
return doBuild();
}
private RolloutRestRequestBody doBuild() {
final RolloutRestRequestBody body = new RolloutRestRequestBody();
body.setName(name);
body.setAmountGroups(groupSize);
body.setTargetFilterQuery(targetFilterQuery);
body.setDistributionSetId(distributionSetId);
body.setSuccessCondition(new RolloutCondition(Condition.THRESHOLD, successThreshold));
body.setErrorCondition(new RolloutCondition(Condition.THRESHOLD, errorThreshold));
return body;
}
}

View File

@@ -0,0 +1,57 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleAssigmentRest;
/**
*
* Builder pattern for building {@link SoftwareModuleAssigmentRest}.
*
* @author Jonathan Knoblauch
*
*/
public class SoftwareModuleAssigmentBuilder {
private final List<Long> ids;
public SoftwareModuleAssigmentBuilder() {
ids = new ArrayList<Long>();
}
/**
* @param id
* the id of the software module
* @return the builder itself
*/
public SoftwareModuleAssigmentBuilder id(final Long id) {
ids.add(id);
return this;
}
/**
* Builds a list with a single entry of {@link SoftwareModuleAssigmentRest}
* which can directly be used in the RESTful-API.
*
* @return a single entry list of {@link SoftwareModuleAssigmentRest}
*/
public List<SoftwareModuleAssigmentRest> build() {
final List<SoftwareModuleAssigmentRest> softwareModuleAssigmentRestList = new ArrayList<>();
for (final Long id : ids) {
final SoftwareModuleAssigmentRest softwareModuleAssigmentRest = new SoftwareModuleAssigmentRest();
softwareModuleAssigmentRest.setId(id);
softwareModuleAssigmentRestList.add(softwareModuleAssigmentRest);
}
return softwareModuleAssigmentRestList;
}
}

View File

@@ -0,0 +1,101 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost;
import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link SoftwareModuleRequestBodyPost}.
*
* @author Jonathan Knoblauch
*
*/
public class SoftwareModuleBuilder {
private String name;
private String version;
private String type;
/**
* @param name
* the name of the software module
* @return the builder itself
*/
public SoftwareModuleBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param version
* the version of the software module
* @return the builder itsefl
*/
public SoftwareModuleBuilder version(final String version) {
this.version = version;
return this;
}
/**
* @param type
* the key of the software module type to be used for this
* software module
* @return the builder itself
*/
public SoftwareModuleBuilder type(final String type) {
this.type = type;
return this;
}
/**
* Builds a list with a single entry of
* {@link SoftwareModuleRequestBodyPost} which can directly be used in the
* RESTful-API.
*
* @return a single entry list of {@link SoftwareModuleRequestBodyPost}
*/
public List<SoftwareModuleRequestBodyPost> build() {
return Lists.newArrayList(doBuild(name));
}
/**
* Builds a list of multiple {@link SoftwareModuleRequestBodyPost} to create
* multiple software module at once. An increasing number will be added to
* the name of the software module. The version and type will remain the
* same.
*
* @param count
* the amount of software module body which should be created
* @return a list of {@link DistributionSetTypeRequestBodyPost}
*/
public List<SoftwareModuleRequestBodyPost> buildAsList(final int count) {
final ArrayList<SoftwareModuleRequestBodyPost> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(name + index));
}
return bodyList;
}
private SoftwareModuleRequestBodyPost doBuild(final String prefixName) {
final SoftwareModuleRequestBodyPost body = new SoftwareModuleRequestBodyPost();
body.setName(prefixName);
body.setVersion(version);
body.setType(type);
return body;
}
}

View File

@@ -0,0 +1,101 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost;
import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link SoftwareModuleRequestBodyPost}.
*
* @author Jonathan Knoblauch
*
*/
public class SoftwareModuleTypeBuilder {
private String key;
private String name;
private String description;
private int maxAssignments;
/**
* @param key
* the key of the software module type
* @return the builder itself
*/
public SoftwareModuleTypeBuilder key(final String key) {
this.key = key;
return this;
}
/**
* @param name
* the name of the software module type
* @return the builder itself
*/
public SoftwareModuleTypeBuilder name(final String name) {
this.name = name;
return this;
}
public SoftwareModuleTypeBuilder description(final String description) {
this.description = description;
return this;
}
public SoftwareModuleTypeBuilder maxAssignments(final int maxAssignments) {
this.maxAssignments = maxAssignments;
return this;
}
/**
* Builds a list with a single entry of
* {@link SoftwareModuleTypeRequestBodyPost} which can directly be used in
* the RESTful-API.
*
* @return a single entry list of {@link SoftwareModuleTypeRequestBodyPost}
*/
public List<SoftwareModuleTypeRequestBodyPost> build() {
return Lists.newArrayList(doBuild(key, name));
}
/**
* Builds a list of multiple {@link SoftwareModuleTypeRequestBodyPost} to
* create multiple software module types at once. An increasing number will
* be added to the name and key of the software module type.
*
* @param count
* the amount of software module type bodies which should be
* created
* @return a list of {@link SoftwareModuleTypeRequestBodyPost}
*/
public List<SoftwareModuleTypeRequestBodyPost> buildAsList(final int count) {
final ArrayList<SoftwareModuleTypeRequestBodyPost> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(key + index, name + index));
}
return bodyList;
}
private SoftwareModuleTypeRequestBodyPost doBuild(final String prefixKey, final String prefixName) {
final SoftwareModuleTypeRequestBodyPost body = new SoftwareModuleTypeRequestBodyPost();
body.setKey(prefixKey);
body.setName(prefixName);
body.setDescription(description);
body.setMaxAssignments(maxAssignments);
return body;
}
}

View File

@@ -0,0 +1,96 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import com.google.common.collect.Lists;
/**
* Builder pattern for building {@link TagRequestBodyPut}.
*
* @author Jonathan Knoblauch
*
*/
public class TagBuilder {
private String name;
private String description;
private String color;
/**
* @param name
* the name of the tag
* @return the builder itself
*/
public TagBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param description
* the description of the tag
* @return the builder itself
*/
public TagBuilder description(final String description) {
this.description = description;
return this;
}
/**
* @param color
* the colour of the tag
* @return the builder itself
*/
public TagBuilder color(final String color) {
this.color = color;
return this;
}
/**
* Builds a list with a single entry of {@link TagRequestBodyPut} which can
* directly be used in the RESTful-API.
*
* @return a single entry list of {@link TagRequestBodyPut}
*/
public List<TagRequestBodyPut> build() {
return Lists.newArrayList(doBuild(name));
}
/**
* Builds a list of multiple {@link TagRequestBodyPut} to create multiple
* tags at once. An increasing number will be added to the name of the tag.
* The color and description will remain the same.
*
* @param count
* the amount of distribution sets body which should be created
* @return a list of {@link TagRequestBodyPut}
*/
public List<TagRequestBodyPut> buildAsList(final int count) {
final ArrayList<TagRequestBodyPut> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(name + index));
}
return bodyList;
}
private TagRequestBodyPut doBuild(final String prefixName) {
final TagRequestBodyPut body = new TagRequestBodyPut();
body.setName(prefixName);
body.setDescription(description);
body.setColour(color);
return body;
}
}

View File

@@ -0,0 +1,98 @@
/**
* 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.client.resource.builder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody;
import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link TargetRequestBody}.
*
* @author Jonathan Knoblauch
*
*/
public class TargetBuilder {
private String controllerId;
private String name;
private String description;
/**
* @param controllerId
* the ID of the controller/target
* @return the builder itself
*/
public TargetBuilder controllerId(final String controllerId) {
this.controllerId = controllerId;
return this;
}
/**
* @param name
* the name of the target
* @return the builder itself
*/
public TargetBuilder name(final String name) {
this.name = name;
return this;
}
/**
* @param description
* the description of the target
* @return the builder itself
*/
public TargetBuilder description(final String description) {
this.description = description;
return this;
}
/**
* Builds a list with a single entry of {@link TargetRequestBody} which can
* directly be used in the RESTful-API.
*
* @return a single entry list of {@link TargetRequestBody}
*/
public List<TargetRequestBody> build() {
return Lists.newArrayList(doBuild(controllerId));
}
/**
* Builds a list of multiple {@link TargetRequestBody} to create multiple
* targets at once. An increasing number will be added to the controllerId
* of the target. The name and description will remain.
*
* @param count
* the amount of software module type bodies which should be
* created
* @return a list of {@link SoftwareModuleTypeRequestBodyPost}
*/
public List<TargetRequestBody> buildAsList(final int count) {
final ArrayList<TargetRequestBody> bodyList = Lists.newArrayList();
for (int index = 0; index < count; index++) {
bodyList.add(doBuild(controllerId + index));
}
return bodyList;
}
private TargetRequestBody doBuild(final String prefixControllerId) {
final TargetRequestBody body = new TargetRequestBody();
body.setControllerId(prefixControllerId);
body.setName(name);
body.setDescription(description);
return body;
}
}

View File

@@ -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.mgmt.client.scenarios;
import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetTypeResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.RolloutResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleTypeResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.TargetResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.RolloutBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Example for creating and starting a Rollout.
*
*/
@Component
public class CreateStartedRolloutExample {
/* known software module type name and key */
private static final String SM_MODULE_TYPE = "firmware";
/* known distribution set type name and key */
private static final String DS_MODULE_TYPE = "firmware";
@Autowired
private DistributionSetResourceClient distributionSetResource;
@Autowired
private SoftwareModuleResourceClient softwareModuleResource;
@Autowired
private TargetResourceClient targetResource;
@Autowired
private RolloutResourceClient rolloutResource;
@Autowired
private DistributionSetTypeResourceClient distributionSetTypeResource;
@Autowired
private SoftwareModuleTypeResourceClient softwareModuleTypeResource;
/**
* Run the Rollout scenario.
*/
public void run() {
// create three SoftwareModuleTypes
final SoftwareModuleTypesRest createdSoftwareModuleTypes = softwareModuleTypeResource.createSoftwareModuleTypes(
new SoftwareModuleTypeBuilder().key(SM_MODULE_TYPE).name(SM_MODULE_TYPE).maxAssignments(1).build())
.getBody();
// create one DistributionSetType
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(DS_MODULE_TYPE)
.name(DS_MODULE_TYPE).mandatorymodules(createdSoftwareModuleTypes.get(0).getModuleId()).build())
.getBody();
// create one DistributionSet
final DistributionSetsRest distributionSetsRest = distributionSetResource.createDistributionSets(
new DistributionSetBuilder().name("rollout-example").version("1.0.0").type(DS_MODULE_TYPE).build())
.getBody();
// create three SoftwareModules
final SoftwareModulesRest softwareModulesRest = softwareModuleResource
.createSoftwareModules(
new SoftwareModuleBuilder().name("firmware").version("1.0.0").type(SM_MODULE_TYPE).build())
.getBody();
// Assign SoftwareModule to DistributionSet
distributionSetResource.assignSoftwareModules(distributionSetsRest.get(0).getDsId(),
new SoftwareModuleAssigmentBuilder().id(softwareModulesRest.get(0).getModuleId()).build());
// create ten targets
targetResource.createTargets(new TargetBuilder().controllerId("00-FF-AA-0").name("00-FF-AA-0")
.description("Targets used for rollout example").buildAsList(10));
// create a Rollout
final RolloutResponseBody rolloutResponseBody = rolloutResource
.create(new RolloutBuilder().name("MyRollout").groupSize(2).targetFilterQuery("name==00-FF-AA-0*")
.distributionSetId(distributionSetsRest.get(0).getDsId()).successThreshold("80")
.errorThreshold("50").build())
.getBody();
// start the created Rollout
rolloutResource.start(rolloutResponseBody.getRolloutId(), false);
}
}

View File

@@ -0,0 +1,134 @@
/**
* 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.client.scenarios;
import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetTypeResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleTypeResourceClient;
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
* Default getting started scenario.
*
*/
@Component
public class GettingStartedDefaultScenario {
private static final Logger LOGGER = LoggerFactory.getLogger(GettingStartedDefaultScenario.class);
/* known software module type name and key */
private static final String SM_MODULE_TYPE = "gettingstarted";
/* known distribution set type name and key */
private static final String DS_MODULE_TYPE = "gettingstarted";
/* known distribution name of this getting started example */
private static final String SM_EXAMPLE_NAME = "gettingstarted-example";
/* known distribution name of this getting started example */
private static final String DS_EXAMPLE_NAME = "gettingstarted-example";
@Autowired
private DistributionSetResourceClient distributionSetResource;
@Autowired
private DistributionSetTypeResourceClient distributionSetTypeResource;
@Autowired
private SoftwareModuleResourceClient softwareModuleResource;
@Autowired
private SoftwareModuleTypeResourceClient softwareModuleTypeResource;
/**
* Run the default getting started scenario.
*/
public void run() {
LOGGER.info("Running Getting-Started-Scenario...");
// create one SoftwareModuleTypes
LOGGER.info("Creating software module type {}", SM_MODULE_TYPE);
final SoftwareModuleTypesRest createdSoftwareModuleTypes = softwareModuleTypeResource.createSoftwareModuleTypes(
new SoftwareModuleTypeBuilder().key(SM_MODULE_TYPE).name(SM_MODULE_TYPE).maxAssignments(1).build())
.getBody();
// create one DistributionSetType
LOGGER.info("Creating distribution set type {}", DS_MODULE_TYPE);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(DS_MODULE_TYPE)
.name(DS_MODULE_TYPE).mandatorymodules(createdSoftwareModuleTypes.get(0).getModuleId()).build());
// create three DistributionSet
final String dsVersion1 = "1.0.0";
final String dsVersion2 = "2.0.0";
final String dsVersion3 = "2.1.0";
LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion1);
final DistributionSetsRest distributionSetsRest1 = distributionSetResource.createDistributionSets(
new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion1).type(DS_MODULE_TYPE).build())
.getBody();
LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion2);
final DistributionSetsRest distributionSetsRest2 = distributionSetResource.createDistributionSets(
new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion2).type(DS_MODULE_TYPE).build())
.getBody();
LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion3);
final DistributionSetsRest distributionSetsRest3 = distributionSetResource.createDistributionSets(
new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion3).type(DS_MODULE_TYPE).build())
.getBody();
// create three SoftwareModules
final String swVersion1 = "1";
final String swVersion2 = "2";
final String swVersion3 = "3";
LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1);
final SoftwareModulesRest softwareModulesRest1 = softwareModuleResource.createSoftwareModules(
new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion1).type(SM_MODULE_TYPE).build())
.getBody();
LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2);
final SoftwareModulesRest softwareModulesRest2 = softwareModuleResource.createSoftwareModules(
new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion2).type(SM_MODULE_TYPE).build())
.getBody();
LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3);
final SoftwareModulesRest softwareModulesRest3 = softwareModuleResource.createSoftwareModules(
new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion3).type(SM_MODULE_TYPE).build())
.getBody();
// Assign SoftwareModules to DistributionSet
LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1,
DS_EXAMPLE_NAME, dsVersion1);
distributionSetResource.assignSoftwareModules(distributionSetsRest1.get(0).getDsId(),
new SoftwareModuleAssigmentBuilder().id(softwareModulesRest1.get(0).getModuleId()).build());
LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2,
DS_EXAMPLE_NAME, dsVersion2);
distributionSetResource.assignSoftwareModules(distributionSetsRest2.get(0).getDsId(),
new SoftwareModuleAssigmentBuilder().id(softwareModulesRest2.get(0).getModuleId()).build());
LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3,
DS_EXAMPLE_NAME, dsVersion3);
distributionSetResource.assignSoftwareModules(distributionSetsRest3.get(0).getDsId(),
new SoftwareModuleAssigmentBuilder().id(softwareModulesRest3.get(0).getModuleId()).build());
}
}

View File

@@ -0,0 +1,14 @@
#
# 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
#
hawkbit.url=localhost:8080
hawkbit.username=admin
hawkbit.password=admin
spring.main.banner-mode=OFF

View File

@@ -0,0 +1,30 @@
<!-- 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 -->
<?xml version="1.0" encoding="UTF-8"?>
<!--
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
-->
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- Log message format -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.eclipse.hawkbit" level="info" />
<root level="error">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -1,186 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.app.Start;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
import feign.Feign;
import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
@Features("Example Tests - Management RESTful API Client")
@Stories("DistrubutionSet Tag Resource")
public class DistributionSetTagTest {
private DistrubutionSetTagResource distrubutionSetTagResource;
private static List<AssignedDistributionSetRequestBody> assignedTargetRequestBodies;
@BeforeClass
public static void startupServer() {
SpringApplication.run(Start.class, new String[0]);
createTargetsAssignment();
assignedTargetRequestBodies.add(new AssignedDistributionSetRequestBody().setDistributionSetId(100L));
}
@Before
public void setup() {
this.distrubutionSetTagResource = createDistrubutionSetTagResource();
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of distrubutionset tag by ID")
@Ignore
public void getDistributionSetTag() {
final TagsRest result = createDistributionSetTags(2);
assertThat(distrubutionSetTagResource.getDistributionSetTag(result.get(0).getTagId()).getName()).isEqualTo(
"Tag0");
deleteDistributionSets(result);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple update of a distrubutionset tag")
@Ignore
public void updateDistributionSetTag() {
final TagsRest created = createDistributionSetTags(10);
distrubutionSetTagResource.updateDistributionSetTag(created.get(0).getTagId(), new TagRequestBodyPut()
.setDescription("Test").setName("Test").setColour("Green"));
final TagRest targetTag = distrubutionSetTagResource.getDistributionSetTag(created.get(0).getTagId());
assertThat(targetTag.getName()).isEqualTo("Test");
assertThat(targetTag.getDescription()).isEqualTo("Test");
assertThat(targetTag.getColour()).isEqualTo("Green");
deleteDistributionSets(created);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of all assigned distrubutionsets by a distrubutionset tag.")
@Ignore
public void getDistributionSetByTagId() {
final TagsRest created = createDistributionSetTags(10);
distrubutionSetTagResource.assignDistributionSets(created.get(2).getTagId(), assignedTargetRequestBodies);
final DistributionSetsRest distributionSetsRest = distrubutionSetTagResource
.getAssignedDistributionSets(created.get(2).getTagId());
assertThat(distributionSetsRest).hasSize(5);
distrubutionSetTagResource.unassignDistributionSets(created.get(2).getTagId());
deleteDistributionSets(created);
}
@Test
@Description("Toggle request to unassigned all assigned distrubutionset and assign all unassigned distrubutionset.")
@Ignore
public void toggleTagAssignment() {
final TagsRest created = createDistributionSetTags(10);
final Long id = created.get(2).getTagId();
distrubutionSetTagResource.assignDistributionSets(id, assignedTargetRequestBodies);
distrubutionSetTagResource.unassignDistributionSet(id, assignedTargetRequestBodies.get(0)
.getDistributionSetId());
DistributionSetTagAssigmentResultRest assigmentResultRest = distrubutionSetTagResource.toggleTagAssignment(id,
assignedTargetRequestBodies);
final TagRest targetTag = distrubutionSetTagResource.getDistributionSetTag(created.get(2).getTagId());
assertThat(assigmentResultRest.getAssignedDistributionSets()).hasSize(1);
assertThat(assigmentResultRest.getUnassignedDistributionSets()).hasSize(0);
assigmentResultRest = distrubutionSetTagResource.toggleTagAssignment(id, assignedTargetRequestBodies);
assertThat(assigmentResultRest.getAssignedDistributionSets()).hasSize(0);
assertThat(assigmentResultRest.getUnassignedDistributionSets()).hasSize(5);
distrubutionSetTagResource.unassignDistributionSets(targetTag.getTagId());
deleteDistributionSets(created);
}
private void deleteDistributionSets(final List<TagRest> tags) {
for (final TagRest tag : tags) {
distrubutionSetTagResource.deleteDistributionSetTag(tag.getTagId());
}
}
private TagsRest createDistributionSetTags(final int number) {
final List<TagRequestBodyPut> tags = new ArrayList<>();
for (int i = 0; i < number; i++) {
tags.add(new TagRequestBodyPut().setDescription("Tag " + i).setName("Tag" + i).setColour("Red"));
}
final TagsRest result = distrubutionSetTagResource.createDistributionSetTags(tags);
assertThat(result).hasSize(number);
return result;
}
private DistrubutionSetTagResource createDistrubutionSetTagResource() {
final DistrubutionSetTagResource distrubutionSetTagResource = Feign.builder().logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder())
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(DistrubutionSetTagResource.class, "http://localhost:8080");
return distrubutionSetTagResource;
}
private static void createTargetsAssignment() {
final List<DistributionSetRequestBodyPost> sets = new ArrayList<>();
assignedTargetRequestBodies = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final DistributionSetRequestBodyPost bodyPost = (DistributionSetRequestBodyPost) new DistributionSetRequestBodyPost()
.setName("Ds" + i).setDescription("Ds" + i).setVersion("" + i);
sets.add(bodyPost);
}
final DistributionSetsRest result = createDistributionSetResource().createDistributionSets(sets);
for (final DistributionSetRest rest : result) {
assignedTargetRequestBodies.add(new AssignedDistributionSetRequestBody().setDistributionSetId(rest
.getDsId()));
}
}
private static DistributionSetResource createDistributionSetResource() {
final DistributionSetResource distributionSetResource = Feign.builder().logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder())
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(DistributionSetResource.class, "http://localhost:8080");
return distributionSetResource;
}
}

View File

@@ -1,182 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.app.Start;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
import feign.Feign;
import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
@Features("Example Tests - Management RESTful API Client")
@Stories("Target Tag Resource")
public class TargetTagTest {
private TargetTagResource targetTagResource;
private static List<AssignedTargetRequestBody> assignedTargetRequestBodies;
@BeforeClass
public static void startupServer() {
SpringApplication.run(Start.class, new String[0]);
createTargetsAssignment();
assignedTargetRequestBodies.add(new AssignedTargetRequestBody().setControllerId("NotExist"));
}
@Before
public void setup() {
this.targetTagResource = createTargetTagResource();
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of target tag by ID")
@Ignore
public void getTargetTag() {
final TagsRest result = createTargetTags(2);
assertThat(targetTagResource.getTargetTag(result.get(0).getTagId()).getName()).isEqualTo("Tag0");
deleteTargets(result);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple update of a target tag")
@Ignore
public void updateTargetTag() {
final TagsRest created = createTargetTags(10);
targetTagResource.updateTagretTag(created.get(0).getTagId(), new TagRequestBodyPut().setDescription("Test")
.setName("Test").setColour("Green"));
final TagRest targetTag = targetTagResource.getTargetTag(created.get(0).getTagId());
assertThat(targetTag.getName()).isEqualTo("Test");
assertThat(targetTag.getDescription()).isEqualTo("Test");
assertThat(targetTag.getColour()).isEqualTo("Green");
deleteTargets(created);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of all assigned targets by a target tag.")
@Ignore
public void getTargetsByTargetTagId() {
final TagsRest created = createTargetTags(10);
final Long tagId = created.get(2).getTagId();
targetTagResource.assignTargets(tagId, assignedTargetRequestBodies);
final TagRest targetTag = targetTagResource.getTargetTag(tagId);
assertThat(targetTagResource.getAssignedTargets(tagId)).hasSize(5);
targetTagResource.unassignTargets(targetTag.getTagId());
deleteTargets(created);
}
@Test
@Description("Toggle request to unassigned all assigned targets and assign all unassigned targets.")
@Ignore
public void toggleTagAssignment() {
final TagsRest created = createTargetTags(10);
final Long id = created.get(2).getTagId();
targetTagResource.assignTargets(id, assignedTargetRequestBodies);
targetTagResource.unassignTarget(id, assignedTargetRequestBodies.get(0).getControllerId());
TargetTagAssigmentResultRest assigmentResultRest = targetTagResource.toggleTagAssignment(id,
assignedTargetRequestBodies);
final TagRest targetTag = targetTagResource.getTargetTag(created.get(2).getTagId());
assertThat(assigmentResultRest.getAssignedTargets()).hasSize(1);
assertThat(assigmentResultRest.getUnassignedTargets()).hasSize(0);
assigmentResultRest = targetTagResource.toggleTagAssignment(id, assignedTargetRequestBodies);
assertThat(assigmentResultRest.getAssignedTargets()).hasSize(0);
assertThat(assigmentResultRest.getUnassignedTargets()).hasSize(5);
targetTagResource.unassignTargets(targetTag.getTagId());
deleteTargets(created);
}
private void deleteTargets(final List<TagRest> tags) {
for (final TagRest tag : tags) {
targetTagResource.deleteTargetTag(tag.getTagId());
}
}
private TagsRest createTargetTags(final int number) {
final List<TagRequestBodyPut> tags = new ArrayList<>();
for (int i = 0; i < number; i++) {
tags.add(new TagRequestBodyPut().setDescription("Tag " + i).setName("Tag" + i).setColour("Red"));
}
final TagsRest result = targetTagResource.createTargetTag(tags);
assertThat(result).hasSize(number);
return result;
}
private TargetTagResource createTargetTagResource() {
final TargetTagResource targetResource = Feign.builder().logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder())
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(TargetTagResource.class, "http://localhost:8080");
return targetResource;
}
private static void createTargetsAssignment() {
final List<TargetRequestBody> targets = new ArrayList<>();
assignedTargetRequestBodies = new ArrayList<>();
for (int i = 0; i < 5; i++) {
targets.add(new TargetRequestBody().setControllerId("test" + i).setName("testDevice"));
}
final TargetsRest result = createTargetResource().createTargets(targets);
for (final TargetRest rest : result) {
assignedTargetRequestBodies.add(new AssignedTargetRequestBody().setControllerId(rest.getControllerId()));
}
}
private static TargetResource createTargetResource() {
final TargetResource targetResource = Feign.builder().logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder())
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(TargetResource.class, "http://localhost:8080");
return targetResource;
}
}

View File

@@ -1,119 +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
*/
package org.eclipse.hawkbit.mgmt.api.client;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.app.Start;
import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Description;
import feign.Feign;
import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Example Tests - Management RESTful API Client")
@Stories("Target Resource")
public class TargetTest {
@BeforeClass
public static void startupServer() {
SpringApplication.run(Start.class, new String[0]);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of target by ID")
@Ignore
public void getTarget() {
final TargetResource targetResource = createTargetResource();
final TargetsRest result = createTargets(targetResource, 1);
assertThat(targetResource.getTarget("test0").getName()).isEqualTo("testDevice");
deleteTargets(targetResource, result);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of all targets with defined page sizing information (i.e. offset and limit).")
@Ignore
public void getTargetsAsPagedListWithDefinedPageSizing() {
final TargetResource targetResource = createTargetResource();
final TargetsRest created = createTargets(targetResource, 20);
final TargetPagedList queryResult = targetResource.getTargets(0, 10);
assertThat(queryResult.getContent()).hasSize(10);
assertThat(queryResult.getTotal()).isEqualTo(20);
assertThat(queryResult.getSize()).isEqualTo(10);
deleteTargets(targetResource, created);
}
// disabled as this runs not on CI environments.
@Test
@Description("Simple request of all targets with defualt paging parameters.")
@Ignore
public void getTargetsAsPagedListWithDefaultPageSizing() {
final TargetResource targetResource = createTargetResource();
final TargetsRest created = createTargets(targetResource, 20);
final TargetPagedList queryResult = targetResource.getTargets();
assertThat(queryResult.getContent()).hasSize(20);
assertThat(queryResult.getTotal()).isEqualTo(20);
assertThat(queryResult.getSize()).isEqualTo(20);
deleteTargets(targetResource, created);
}
private void deleteTargets(final TargetResource targetResource, final List<TargetRest> targets) {
for (final TargetRest targetRest : targets) {
targetResource.deleteTarget(targetRest.getControllerId());
}
}
private TargetsRest createTargets(final TargetResource targetResource, final int number) {
final List<TargetRequestBody> targets = new ArrayList<>();
for (int i = 0; i < number; i++) {
targets.add(new TargetRequestBody().setControllerId("test" + i).setName("testDevice"));
}
final TargetsRest result = targetResource.createTargets(targets);
assertThat(result).hasSize(number);
return result;
}
private TargetResource createTargetResource() {
final TargetResource targetResource = Feign.builder().logger(new Logger.ErrorLogger())
.logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder())
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(TargetResource.class, "http://localhost:8080");
return targetResource;
}
}

View File

@@ -51,7 +51,16 @@ public enum TargetFields implements FieldNameProvider {
*/
ATTRIBUTE("targetInfo.controllerAttributes", true),
/**
* distribution sets which is assigned to the target.
*/
ASSIGNEDDS("assignedDistributionSet", "name", "version"),
/**
* distribution sets which is installed on the target.
*/
INSTALLEDDS("targetInfo.installedDistributionSet", "name", "version"),
/**
* The tags field.
*/

View File

@@ -298,20 +298,7 @@ public class AmqpMessageHandlerService {
*/
private void updateActionStatus(final Message message) {
final ActionUpdateStatus actionUpdateStatus = convertMessage(message, ActionUpdateStatus.class);
final Long actionId = actionUpdateStatus.getActionId();
LOG.debug("Target notifies intermediate about action {} with status {}.", actionId, actionUpdateStatus
.getActionStatus().name());
if (actionId == null) {
logAndThrowMessageError(message, "Invalid message no action id");
}
final Action action = controllerManagement.findActionWithDetails(actionId);
if (action == null) {
logAndThrowMessageError(message, "Got intermediate notification about action " + actionId
+ " but action does not exist");
}
final Action action = checkActionExist(message, actionUpdateStatus);
final ActionStatus actionStatus = new ActionStatus();
final List<String> messageText = actionUpdateStatus.getMessage();
@@ -362,6 +349,29 @@ public class AmqpMessageHandlerService {
}
}
/**
* @param message
* @param actionUpdateStatus
* @return
*/
private Action checkActionExist(final Message message, final ActionUpdateStatus actionUpdateStatus) {
final Long actionId = actionUpdateStatus.getActionId();
LOG.debug("Target notifies intermediate about action {} with status {}.", actionId, actionUpdateStatus
.getActionStatus().name());
if (actionId == null) {
logAndThrowMessageError(message, "Invalid message no action id");
}
final Action action = controllerManagement.findActionWithDetails(actionId);
if (action == null) {
logAndThrowMessageError(message, "Got intermediate notification about action " + actionId
+ " but action does not exist");
}
return action;
}
private void handleCancelRejected(final Message message, final Action action, final ActionStatus actionStatus) {
if (action.isCancelingOrCanceled()) {

View File

@@ -161,7 +161,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Override
protected Map<String, Object> getVendorProperties() {
final Map<String, Object> properties = new HashMap<String, Object>();
final Map<String, Object> properties = new HashMap<>();
// Turn off dynamic weaving to disable LTW lookup in static weaving mode
properties.put("eclipselink.weaving", "false");
// needed for reports

View File

@@ -8,19 +8,22 @@
*/
package org.eclipse.hawkbit.report.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* A data report series which contains a list of {@link DataReportSeriesItem}.
*
*
*
*
* @param <T>
* the type of the report series item
*/
public class DataReportSeries<T extends Object> extends AbstractReportSeries {
public class DataReportSeries<T extends Serializable> extends AbstractReportSeries {
private static final long serialVersionUID = 1L;
private final List<DataReportSeriesItem<T>> data = new ArrayList<>();
@@ -46,7 +49,7 @@ public class DataReportSeries<T extends Object> extends AbstractReportSeries {
}
private void setData(final List<DataReportSeriesItem<T>> values) {
this.data.clear();
data.clear();
data.addAll(values);
}

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.report.model;
import java.io.Serializable;
/**
* An data report series item which contains a type and a value.
*
@@ -16,8 +18,9 @@ package org.eclipse.hawkbit.report.model;
* @param <T>
* the type of the report series item
*/
public class DataReportSeriesItem<T extends Object> {
public class DataReportSeriesItem<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 1L;
private final T type;
private final Number data;

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.report.model;
import java.io.Serializable;
/**
* A double data series which contains an inner and an outer series ideal for
* showing donut charts.
@@ -17,7 +19,7 @@ package org.eclipse.hawkbit.report.model;
* @param <T>
* The type parameter for the report series data
*/
public class InnerOuterDataReportSeries<T> {
public class InnerOuterDataReportSeries<T extends Serializable> {
private final DataReportSeries<T> innerSeries;
private final DataReportSeries<T> outerSeries;

View File

@@ -22,10 +22,6 @@ import java.util.stream.Collectors;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagAssigmentResultEvent;
@@ -53,13 +49,13 @@ import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.specifications.DistributionSetSpecification;
import org.eclipse.hawkbit.repository.specifications.DistributionSetTypeSpecification;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@@ -203,7 +199,8 @@ public class DistributionSetManagement {
}
final DistributionSetTagAssigmentResult resultAssignment = result;
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
afterCommit
.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
// no reason to persist the tag
entityManager.detach(myTag);
@@ -263,7 +260,7 @@ public class DistributionSetManagement {
@Transactional
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
public void deleteDistributionSet(@NotNull final DistributionSet set) {
this.deleteDistributionSet(set.getId());
deleteDistributionSet(set.getId());
}
/**
@@ -321,14 +318,10 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
public DistributionSet createDistributionSet(@NotNull final DistributionSet dSet) {
prepareDsSave(dSet);
if (dSet.getType() == null) {
dSet.setType(systemManagement.getTenantMetadata().getDefaultDsType());
}
final DistributionSet result = distributionSetRepository.save(dSet);
return result;
return distributionSetRepository.save(dSet);
}
private void prepareDsSave(final DistributionSet dSet) {
@@ -400,7 +393,7 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
public DistributionSet unassignSoftwareModule(@NotNull final DistributionSet ds,
final SoftwareModule softwareModule) {
final Set<SoftwareModule> softwareModules = new HashSet<SoftwareModule>();
final Set<SoftwareModule> softwareModules = new HashSet<>();
softwareModules.add(softwareModule);
ds.removeModule(softwareModule);
checkDistributionSetSoftwareModulesIsAllowedToModify(ds, softwareModules);
@@ -491,20 +484,11 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
private DistributionSet findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
final DistributionSetFilter distributionSetFilter) {
final List<Specification<DistributionSet>> specList = buildDistributionSetSpecifications(distributionSetFilter);
Specifications<DistributionSet> specs = null;
if (!specList.isEmpty()) {
specs = Specifications.where(specList.get(0));
if (specList == null || specList.isEmpty()) {
return null;
}
if (specList.size() > 1) {
specList.remove(0);
for (final Specification<DistributionSet> s : specList) {
specs = specs.and(s);
}
}
return distributionSetRepository.findOne(specs);
return distributionSetRepository.findOne(SpecificationsBuilder.combineWithAnd(specList));
}
/**
@@ -531,7 +515,7 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Page<DistributionSet> findDistributionSetsAll(@NotNull final Pageable pageReq, final Boolean deleted,
final Boolean complete) {
final List<Specification<DistributionSet>> specList = new ArrayList<Specification<DistributionSet>>();
final List<Specification<DistributionSet>> specList = new ArrayList<>();
if (deleted != null) {
final Specification<DistributionSet> spec = DistributionSetSpecification.isDeleted(deleted);
@@ -563,7 +547,7 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Page<DistributionSet> findDistributionSetsAll(@NotNull final Specification<DistributionSet> spec,
@NotNull final Pageable pageReq, final Boolean deleted) {
final List<Specification<DistributionSet>> specList = new ArrayList<Specification<DistributionSet>>();
final List<Specification<DistributionSet>> specList = new ArrayList<>();
if (deleted != null) {
specList.add(DistributionSetSpecification.isDeleted(deleted));
}
@@ -635,17 +619,6 @@ public class DistributionSetManagement {
return new PageImpl<>(resultSet, pageable, findDistributionSetsByFilters.getTotalElements());
}
private Long countDistributionSetByCriteriaAPI(@NotEmpty final List<Specification<DistributionSet>> specList) {
Specifications<DistributionSet> specs = Specifications.where(specList.get(0));
if (specList.size() > 1) {
for (final Specification<DistributionSet> s : specList.subList(1, specList.size())) {
specs = specs.and(s);
}
}
return distributionSetRepository.count(specs);
}
/**
* Find distribution set by name and version.
*
@@ -689,12 +662,12 @@ public class DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Long countDistributionSetsAll() {
final List<Specification<DistributionSet>> specList = new ArrayList<Specification<DistributionSet>>();
final List<Specification<DistributionSet>> specList = new ArrayList<>();
final Specification<DistributionSet> spec = DistributionSetSpecification.isDeleted(Boolean.FALSE);
specList.add(spec);
return countDistributionSetByCriteriaAPI(specList);
return distributionSetRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
/**
@@ -869,17 +842,10 @@ public class DistributionSetManagement {
public Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(
@NotNull final Long distributionSetId, @NotNull final Pageable pageable) {
return distributionSetMetadataRepository.findAll(new Specification<DistributionSetMetadata>() {
@Override
public Predicate toPredicate(final Root<DistributionSetMetadata> root, final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
final Predicate predicate = cb.equal(
root.get(DistributionSetMetadata_.distributionSet).get(DistributionSet_.id), distributionSetId);
return predicate;
}
}, pageable);
return distributionSetMetadataRepository.findAll(
(Specification<DistributionSetMetadata>) (root, query, cb) -> cb.equal(
root.get(DistributionSetMetadata_.distributionSet).get(DistributionSet_.id), distributionSetId),
pageable);
}
@@ -899,14 +865,14 @@ public class DistributionSetManagement {
public Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(
@NotNull final Long distributionSetId, @NotNull final Specification<DistributionSetMetadata> spec,
@NotNull final Pageable pageable) {
return distributionSetMetadataRepository.findAll(new Specification<DistributionSetMetadata>() {
@Override
public Predicate toPredicate(final Root<DistributionSetMetadata> root, final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get(DistributionSetMetadata_.distributionSet).get(DistributionSet_.id),
distributionSetId), spec.toPredicate(root, query, cb));
}
}, pageable);
return distributionSetMetadataRepository
.findAll(
(Specification<DistributionSetMetadata>) (root, query,
cb) -> cb.and(
cb.equal(root.get(DistributionSetMetadata_.distributionSet)
.get(DistributionSet_.id), distributionSetId),
spec.toPredicate(root, query, cb)),
pageable);
}
/**
@@ -956,7 +922,7 @@ public class DistributionSetManagement {
/**
* Checking Distribution Set is already using while assign Software module.
*
*
* @param distributionSet
* @param softwareModules
*/
@@ -969,9 +935,9 @@ public class DistributionSetManagement {
private List<Specification<DistributionSet>> buildDistributionSetSpecifications(
final DistributionSetFilter distributionSetFilter) {
final List<Specification<DistributionSet>> specList = new ArrayList<Specification<DistributionSet>>();
final List<Specification<DistributionSet>> specList = new ArrayList<>();
Specification<DistributionSet> spec = null;
Specification<DistributionSet> spec;
if (null != distributionSetFilter.getIsComplete()) {
spec = DistributionSetSpecification.isCompleted(distributionSetFilter.getIsComplete());
@@ -1053,21 +1019,12 @@ public class DistributionSetManagement {
*/
private Page<DistributionSet> findByCriteriaAPI(@NotNull final Pageable pageable,
final List<Specification<DistributionSet>> specList) {
Specifications<DistributionSet> specs = null;
if (!specList.isEmpty()) {
specs = Specifications.where(specList.get(0));
}
if (specList.size() > 1) {
for (final Specification<DistributionSet> s : specList.subList(1, specList.size())) {
specs = specs.and(s);
}
if (specList == null || specList.isEmpty()) {
return distributionSetRepository.findAll(pageable);
}
if (specs == null) {
return distributionSetRepository.findAll(pageable);
} else {
return distributionSetRepository.findAll(specs, pageable);
}
return distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable);
}
private void checkAndThrowAlreadyIfDistributionSetMetadataExists(final DsMetadataCompositeKey metadataId) {

View File

@@ -213,8 +213,8 @@ public class ReportManagement {
* count
*/
@Cacheable("targetsCreatedOverPeriod")
public <T> DataReportSeries<T> targetsCreatedOverPeriod(final DateType<T> dateType, final LocalDateTime from,
final LocalDateTime to) {
public <T extends Serializable> DataReportSeries<T> targetsCreatedOverPeriod(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
.createNativeQuery(getTargetsCreatedQueryTemplate(dateType, from, to));
final List<Object[]> resultList = createNativeQuery.getResultList();
@@ -223,8 +223,7 @@ public class ReportManagement {
.map(r -> new DataReportSeriesItem<>(dateType.format((String) r[0]), ((Number) r[1]).longValue()))
.collect(Collectors.toList());
final DataReportSeries<T> report = new DataReportSeries<>("CreatedTargets", reportItems);
return report;
return new DataReportSeries<>("CreatedTargets", reportItems);
}
private String getTargetsCreatedQueryTemplate(final DateType<?> dateType, final LocalDateTime from,
@@ -276,8 +275,8 @@ public class ReportManagement {
* count
*/
@Cacheable("feedbackReceivedOverTime")
public <T> DataReportSeries<T> feedbackReceivedOverTime(final DateType<T> dateType, final LocalDateTime from,
final LocalDateTime to) {
public <T extends Serializable> DataReportSeries<T> feedbackReceivedOverTime(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
.createNativeQuery(getFeedbackReceivedQueryTemplate(dateType, from, to));
final List<Object[]> resultList = createNativeQuery.getResultList();
@@ -286,8 +285,7 @@ public class ReportManagement {
.map(r -> new DataReportSeriesItem<>(dateType.format((String) r[0]), ((Number) r[1]).longValue()))
.collect(Collectors.toList());
final DataReportSeries<T> report = new DataReportSeries<>("FeedbackRecieved", reportItems);
return report;
return new DataReportSeries<>("FeedbackRecieved", reportItems);
}
/**
@@ -433,7 +431,7 @@ public class ReportManagement {
}
private DataReportSeriesItem<String> toItem() {
return new DataReportSeriesItem<String>(name.getName() != null ? name.getName() : "misc", count);
return new DataReportSeriesItem<>(name.getName() != null ? name.getName() : "misc", count);
}
}

View File

@@ -40,6 +40,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.SoftwareModule_;
import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.specifications.SoftwareModuleSpecification;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.AuditorAware;
@@ -48,7 +49,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@@ -198,7 +198,7 @@ public class SoftwareManagement {
/**
* retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType}
* .
*
*
* @param pageable
* page parameters
* @param type
@@ -209,7 +209,7 @@ public class SoftwareManagement {
public Slice<SoftwareModule> findSoftwareModulesByType(@NotNull final Pageable pageable,
@NotNull final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.equalType(type);
specList.add(spec);
@@ -230,7 +230,7 @@ public class SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Long countSoftwareModulesByType(@NotNull final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.equalType(type);
specList.add(spec);
@@ -257,7 +257,7 @@ public class SoftwareManagement {
/**
* retrieves {@link SoftwareModule}s by their name AND version.
*
*
* @param name
* of the {@link SoftwareModule}
* @param version
@@ -273,7 +273,7 @@ public class SoftwareManagement {
/**
* Deletes the given {@link SoftwareModule} {@link Entity}.
*
*
* @param bsm
* is the {@link SoftwareModule} to be deleted
*/
@@ -291,26 +291,12 @@ public class SoftwareManagement {
private Slice<SoftwareModule> findSwModuleByCriteriaAPI(@NotNull final Pageable pageable,
@NotEmpty final List<Specification<SoftwareModule>> specList) {
Specifications<SoftwareModule> specs = Specifications.where(specList.get(0));
if (specList.size() > 1) {
for (final Specification<SoftwareModule> s : specList.subList(1, specList.size())) {
specs = specs.and(s);
}
}
return criteriaNoCountDao.findAll(specs, pageable, SoftwareModule.class);
return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable,
SoftwareModule.class);
}
private Long countSwModuleByCriteriaAPI(@NotEmpty final List<Specification<SoftwareModule>> specList) {
Specifications<SoftwareModule> specs = Specifications.where(specList.get(0));
if (specList.size() > 1) {
for (final Specification<SoftwareModule> s : specList.subList(1, specList.size())) {
specs = specs.and(s);
}
}
return softwareModuleRepository.count(specs);
return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
private void deleteGridFsArtifacts(final SoftwareModule swModule) {
@@ -321,7 +307,7 @@ public class SoftwareManagement {
/**
* Deletes {@link SoftwareModule}s which is any if the given ids.
*
*
* @param ids
* of the Software Moduels to be deleted
*/
@@ -366,20 +352,16 @@ public class SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Slice<SoftwareModule> findSoftwareModulesAll(@NotNull final Pageable pageable) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
spec = new Specification<SoftwareModule>() {
@Override
public Predicate toPredicate(final Root<SoftwareModule> root, final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
}
return cb.conjunction();
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(spec);
@@ -396,7 +378,7 @@ public class SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Long countSoftwareModulesAll() {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
@@ -479,7 +461,7 @@ public class SoftwareManagement {
public Slice<SoftwareModule> findSoftwareModuleByFilters(@NotNull final Pageable pageable, final String searchText,
final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
@@ -494,15 +476,11 @@ public class SoftwareManagement {
specList.add(spec);
}
spec = new Specification<SoftwareModule>() {
@Override
public Predicate toPredicate(final Root<SoftwareModule> root, final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
}
return cb.conjunction();
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(spec);
@@ -592,7 +570,7 @@ public class SoftwareManagement {
private List<Specification<SoftwareModule>> buildSpecificationList(final String searchText,
final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
if (!Strings.isNullOrEmpty(searchText)) {
specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText));
}
@@ -631,7 +609,7 @@ public class SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<Specification<SoftwareModule>>();
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
@@ -788,7 +766,7 @@ public class SoftwareManagement {
/**
* creates or updates a single software module meta data entry.
*
*
* @param metadata
* the meta data entry to create or update
* @return the updated or created software module meta data entry
@@ -813,7 +791,7 @@ public class SoftwareManagement {
/**
* creates a list of software module meta data entries.
*
*
* @param metadata
* the meta data entries to create or update
* @return the updated or created software module meta data entries
@@ -835,7 +813,7 @@ public class SoftwareManagement {
/**
* updates a distribution set meta data value if corresponding entry exists.
*
*
* @param metadata
* the meta data entry to be updated
* @return the updated meta data entry
@@ -858,7 +836,7 @@ public class SoftwareManagement {
/**
* deletes a software module meta data entry.
*
*
* @param id
* the ID of the software module meta data to delete
*/
@@ -871,7 +849,7 @@ public class SoftwareManagement {
/**
* finds all meta data by the given software module id.
*
*
* @param swId
* the software module id to retrieve the meta data from
* @param pageable
@@ -887,7 +865,7 @@ public class SoftwareManagement {
/**
* finds all meta data by the given software module id.
*
*
* @param softwareModuleId
* the software module id to retrieve the meta data from
* @param spec
@@ -900,20 +878,19 @@ public class SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public Page<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId,
@NotNull final Specification<SoftwareModuleMetadata> spec, @NotNull final Pageable pageable) {
return softwareModuleMetadataRepository.findAll(new Specification<SoftwareModuleMetadata>() {
@Override
public Predicate toPredicate(final Root<SoftwareModuleMetadata> root, final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get(SoftwareModuleMetadata_.softwareModule).get(SoftwareModule_.id),
softwareModuleId), spec.toPredicate(root, query, cb));
}
}, pageable);
return softwareModuleMetadataRepository
.findAll(
(Specification<SoftwareModuleMetadata>) (root, query,
cb) -> cb.and(
cb.equal(root.get(SoftwareModuleMetadata_.softwareModule)
.get(SoftwareModule_.id), softwareModuleId),
spec.toPredicate(root, query, cb)),
pageable);
}
/**
* finds a single software module meta data by its id.
*
*
* @param id
* the id of the software module meta data containing the meta
* data key and the ID of the software module

View File

@@ -16,6 +16,7 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.specifications.TargetFilterQuerySpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
@@ -33,7 +34,7 @@ import com.google.common.base.Strings;
/**
* Business service facade for managing {@link TargetFilterQuery}s.
*
*
*
*
*/
@@ -47,7 +48,7 @@ public class TargetFilterQueryManagement {
/**
* creating new {@link TargetFilterQuery}.
*
*
* @param customTargetFilter
* @return the created {@link TargetFilterQuery}
*/
@@ -60,13 +61,12 @@ public class TargetFilterQueryManagement {
if (targetFilterQueryRepository.findByName(customTargetFilter.getName()) != null) {
throw new EntityAlreadyExistsException(customTargetFilter.getName());
}
final TargetFilterQuery filter = targetFilterQueryRepository.save(customTargetFilter);
return filter;
return targetFilterQueryRepository.save(customTargetFilter);
}
/**
* Delete target filter query.
*
*
* @param targetFilterQueryId
* IDs of target filter query to be deleted
*/
@@ -78,9 +78,9 @@ public class TargetFilterQueryManagement {
}
/**
*
*
* Retrieves all target filter query{@link TargetFilterQuery}.
*
*
* @param pageable
* pagination parameter
* @return the found {@link TargetFilterQuery}s
@@ -92,8 +92,8 @@ public class TargetFilterQueryManagement {
/**
* Retrieves all target filter query which {@link TargetFilterQuery}.
*
*
*
*
* @param pageable
* pagination parameter
* @param name
@@ -102,7 +102,7 @@ public class TargetFilterQueryManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public Page<TargetFilterQuery> findTargetFilterQueryByFilters(@NotNull final Pageable pageable, final String name) {
final List<Specification<TargetFilterQuery>> specList = new ArrayList<Specification<TargetFilterQuery>>();
final List<Specification<TargetFilterQuery>> specList = new ArrayList<>();
if (!Strings.isNullOrEmpty(name)) {
specList.add(TargetFilterQuerySpecification.likeName(name));
}
@@ -110,7 +110,7 @@ public class TargetFilterQueryManagement {
}
/**
*
*
* @param pageable
* pagination parameter
* @param specList
@@ -119,29 +119,21 @@ public class TargetFilterQueryManagement {
*/
private Page<TargetFilterQuery> findTargetFilterQueryByCriteriaAPI(@NotNull final Pageable pageable,
final List<Specification<TargetFilterQuery>> specList) {
Specifications<TargetFilterQuery> specs = null;
if (!specList.isEmpty()) {
specs = Specifications.where(specList.get(0));
}
if (specList.size() > 1) {
for (final Specification<TargetFilterQuery> s : specList.subList(1, specList.size())) {
specs = specs.and(s);
}
}
if (specs == null) {
if (specList == null || specList.isEmpty()) {
return targetFilterQueryRepository.findAll(pageable);
} else {
return targetFilterQueryRepository.findAll(specs, pageable);
}
final Specifications<TargetFilterQuery> specs = SpecificationsBuilder.combineWithAnd(specList);
return targetFilterQueryRepository.findAll(specs, pageable);
}
/**
* Find target filter query by name.
*
*
* @param targetFilterQueryName
* Target filter query name
* @return the found {@link TargetFilterQuery}
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public TargetFilterQuery findTargetFilterQueryByName(@NotNull final String targetFilterQueryName) {
@@ -150,11 +142,11 @@ public class TargetFilterQueryManagement {
/**
* Find target filter query by id.
*
*
* @param targetFilterQueryId
* Target filter query id
* @return the found {@link TargetFilterQuery}
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public TargetFilterQuery findTargetFilterQueryById(@NotNull final Long targetFilterQueryId) {
@@ -163,7 +155,7 @@ public class TargetFilterQueryManagement {
/**
* updates the {@link TargetFilterQuery}.
*
*
* @param targetFilterQuery
* to be updated
* @return the updated {@link TargetFilterQuery}

View File

@@ -47,6 +47,7 @@ import org.eclipse.hawkbit.repository.model.TargetTagAssigmentResult;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.Target_;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.specifications.TargetSpecifications;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
@@ -59,7 +60,6 @@ import org.springframework.data.domain.SliceImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@@ -508,39 +508,18 @@ public class TargetManagement {
* @return the page with the found {@link Target}
*/
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<Target>> specList) {
final Specifications<Target> specs = creatingTargetSpecifications(specList);
if (specs == null) {
if (specList == null || specList.isEmpty()) {
return criteriaNoCountDao.findAll(pageable, Target.class);
} else {
return criteriaNoCountDao.findAll(specs, pageable, Target.class);
}
return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, Target.class);
}
private Long countByCriteriaAPI(final List<Specification<Target>> specList) {
final Specifications<Target> specs = creatingTargetSpecifications(specList);
if (specs == null) {
if (specList == null || specList.isEmpty()) {
return targetRepository.count();
} else {
return targetRepository.count(specs);
}
}
private static Specifications<Target> creatingTargetSpecifications(final List<Specification<Target>> specList) {
Specifications<Target> specs = null;
if (!specList.isEmpty()) {
specs = Specifications.where(specList.get(0));
}
if (specList.size() > 1) {
specList.remove(0);
for (final Specification<Target> s : specList) {
specs = specs.and(s);
}
}
return specs;
return targetRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
/**

View File

@@ -77,7 +77,7 @@ public class Rollout extends NamedEntity {
private int rolloutGroupsCreated = 0;
@Transient
private TotalTargetCountStatus totalTargetCountStatus;
private transient TotalTargetCountStatus totalTargetCountStatus;
/**
* @return the distributionSet
@@ -234,7 +234,7 @@ public class Rollout extends NamedEntity {
*/
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
this.totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
}
return totalTargetCountStatus;
}
@@ -255,11 +255,11 @@ public class Rollout extends NamedEntity {
}
/**
*
*
* @author Michael Hirsch
*
*/
public static enum RolloutStatus {
public enum RolloutStatus {
/**
* Rollouts is beeing created.

View File

@@ -27,7 +27,7 @@ import javax.persistence.UniqueConstraint;
/**
* JPA entity definition of persisting a group of an rollout.
*
*
* @author Michael Hirsch
*
*/
@@ -116,7 +116,7 @@ public class RolloutGroup extends NamedEntity {
}
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
this.successCondition = finishCondition;
successCondition = finishCondition;
}
public String getSuccessConditionExp() {
@@ -124,7 +124,7 @@ public class RolloutGroup extends NamedEntity {
}
public void setSuccessConditionExp(final String finishExp) {
this.successConditionExp = finishExp;
successConditionExp = finishExp;
}
public RolloutGroupErrorCondition getErrorCondition() {
@@ -140,7 +140,7 @@ public class RolloutGroup extends NamedEntity {
}
public void setErrorConditionExp(final String errorExp) {
this.errorConditionExp = errorExp;
errorConditionExp = errorExp;
}
public RolloutGroupErrorAction getErrorAction() {
@@ -188,7 +188,7 @@ public class RolloutGroup extends NamedEntity {
*/
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
this.totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
}
return totalTargetCountStatus;
}
@@ -210,7 +210,7 @@ public class RolloutGroup extends NamedEntity {
}
/**
*
*
* @author Michael Hirsch
*
*/
@@ -343,7 +343,7 @@ public class RolloutGroup extends NamedEntity {
}
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
this.successCondition = finishCondition;
successCondition = finishCondition;
}
public String getSuccessConditionExp() {
@@ -351,7 +351,7 @@ public class RolloutGroup extends NamedEntity {
}
public void setSuccessConditionExp(final String finishConditionExp) {
this.successConditionExp = finishConditionExp;
successConditionExp = finishConditionExp;
}
public RolloutGroupSuccessAction getSuccessAction() {
@@ -416,7 +416,7 @@ public class RolloutGroup extends NamedEntity {
/**
* Sets the finish condition and expression on the builder.
*
*
* @param condition
* the finish condition
* @param expression
@@ -432,7 +432,7 @@ public class RolloutGroup extends NamedEntity {
/**
* Sets the success action and expression on the builder.
*
*
* @param action
* the success action
* @param expression
@@ -448,7 +448,7 @@ public class RolloutGroup extends NamedEntity {
/**
* Sets the error condition and expression on the builder.
*
*
* @param condition
* the error condition
* @param expression
@@ -464,7 +464,7 @@ public class RolloutGroup extends NamedEntity {
/**
* Sets the error action and expression on the builder.
*
*
* @param action
* the error action
* @param expression

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
@@ -30,16 +31,18 @@ import javax.persistence.Table;
@IdClass(RolloutTargetGroupId.class)
@Entity
@Table(name = "sp_rollouttargetgroup")
public class RolloutTargetGroup {
public class RolloutTargetGroup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(targetEntity = RolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group"))
@JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group") )
private RolloutGroup rolloutGroup;
@Id
@ManyToOne(targetEntity = Target.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target"))
@JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target") )
private Target target;
@OneToMany(targetEntity = Action.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })

View File

@@ -9,12 +9,12 @@
package org.eclipse.hawkbit.repository.model;
import java.util.Collections;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
/**
*
*
* Store all states with the target count of a rollout or rolloutgroup.
*
*/
@@ -27,12 +27,12 @@ public class TotalTargetCountStatus {
SCHEDULED, RUNNING, ERROR, FINISHED, CANCELLED, NOTSTARTED
}
private final Map<Status, Long> statusTotalCountMap = new HashMap<>();
private final Map<Status, Long> statusTotalCountMap = new EnumMap<>(Status.class);
private final Long totalTargetCount;
/**
* Create a new states map with the target count for each state.
*
*
* @param targetCountActionStatus
* the action state map
* @param totalTargets
@@ -46,7 +46,7 @@ public class TotalTargetCountStatus {
/**
* Create a new states map with the target count for each state.
*
*
* @param totalTargetCount
* the total target count
*/
@@ -56,7 +56,7 @@ public class TotalTargetCountStatus {
/**
* The current state mape which the total target count
*
*
* @return the statusTotalCountMap the state map
*/
public Map<Status, Long> getStatusTotalCountMap() {
@@ -65,7 +65,7 @@ public class TotalTargetCountStatus {
/**
* Gets the total target count from a state.
*
*
* @param status
* the state key
* @return the current target count cannot be <null>
@@ -77,7 +77,7 @@ public class TotalTargetCountStatus {
/**
* Populate all target status to a the given map
*
*
* @param statusTotalCountMap
* the map
* @param rolloutStatusCountItems

View File

@@ -0,0 +1,46 @@
/**
* 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.specifications;
import java.util.List;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
/**
* Helper class to easily combine {@link Specification} instances.
*
*/
public final class SpecificationsBuilder {
private SpecificationsBuilder() {
}
/**
* Combine all given specification with and. The first specification is the
* where clause.
*
* @param specList
* all specification wich will combine
* @return <null> if the given specification list is empty
*/
public static <T> Specifications<T> combineWithAnd(final List<Specification<T>> specList) {
if (specList.isEmpty()) {
return null;
}
Specifications<T> specs = Specifications.where(specList.get(0));
specList.remove(0);
for (final Specification<T> specification : specList) {
specs = specs.and(specification);
}
return specs;
}
}

View File

@@ -16,7 +16,19 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
*/
public interface RolloutGroupConditionEvaluator {
boolean verifyExpression(final String expression);
default boolean verifyExpression(final String expression) {
// percentage value between 0 and 100
try {
final Integer value = Integer.valueOf(expression);
if (value >= 0 || value <= 100) {
return true;
}
return true;
} catch (final NumberFormatException e) {
return false;
}
}
boolean eval(Rollout rollout, RolloutGroup rolloutGroup, final String expression);
}

View File

@@ -18,31 +18,16 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
*
*/
@Component("thresholdRolloutGroupErrorCondition")
public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditionEvaluator {
private static Logger logger = LoggerFactory.getLogger(ThresholdRolloutGroupErrorCondition.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupErrorCondition.class);
@Autowired
private ActionRepository actionRepository;
@Override
public boolean verifyExpression(final String expression) {
// percentage value between 0 and 100
try {
final Integer value = Integer.valueOf(expression);
if (value >= 0 || value <= 100) {
return true;
}
return true;
} catch (final RuntimeException e) {
}
return false;
}
@Override
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup(rollout, rolloutGroup);
@@ -60,7 +45,7 @@ public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditio
// calculate threshold
return ((float) error / (float) totalGroup) > ((float) threshold / 100F);
} catch (final NumberFormatException e) {
logger.error("Cannot evaluate condition expression " + expression, e);
LOGGER.error("Cannot evaluate condition expression " + expression, e);
return false;
}
}

View File

@@ -12,47 +12,41 @@ import org.eclipse.hawkbit.repository.ActionRepository;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
*
*/
@Component("thresholdRolloutGroupSuccessCondition")
public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupConditionEvaluator {
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupSuccessCondition.class);
@Autowired
private ActionRepository actionRepository;
@Override
public boolean verifyExpression(final String expression) {
// percentage value between 0 and 100
try {
final Integer value = Integer.valueOf(expression);
if (value >= 0 || value <= 100) {
return true;
}
return true;
} catch (final RuntimeException e) {
}
return false;
}
@Override
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
final Long totalGroup = rolloutGroup.getTotalTargets();
final Long finished = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(),
final Long finished = this.actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(),
rolloutGroup.getId(), Action.Status.FINISHED);
final Integer threshold = Integer.valueOf(expression);
try {
final Integer threshold = Integer.valueOf(expression);
if (totalGroup == 0) {
// in case e.g. targets has been deleted we don't have any actions
// left for this group, so the group is finished
return true;
if (totalGroup == 0) {
// in case e.g. targets has been deleted we don't have any
// actions
// left for this group, so the group is finished
return true;
}
// calculate threshold
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);
} catch (final NumberFormatException e) {
LOGGER.error("Cannot evaluate condition expression " + expression, e);
return false;
}
// calculate threshold
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);
}
}

View File

@@ -0,0 +1,365 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetPagedList;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.distributionset.TargetAssignmentRequestBody;
import org.eclipse.hawkbit.rest.resource.model.distributionset.TargetAssignmentResponseBody;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleAssigmentRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulePagedList;
import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList;
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;
/**
* REST Resource handling for DistributionSet CRUD operations.
*/
@RequestMapping(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
public interface DistributionSetRestApi {
/**
* Handles the GET request of retrieving all DistributionSets .
*
* @param pagingOffsetParam
* the offset of list of sets 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 set 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 })
public ResponseEntity<DistributionSetPagedList> getDistributionSets(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single DistributionSet .
*
* @param distributionSetId
* the ID of the set to retrieve
*
* @return a single DistributionSet with status OK.
*
* @throws EntityNotFoundException
* in case no DistributionSet with the given ID exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getDistributionSet(
@PathVariable("distributionSetId") final Long distributionSetId);
/**
* Handles the POST request of creating new distribution sets . The request
* body must always be a list of sets.
*
* @param sets
* the DistributionSets to be created.
* @return In case all sets could successful created the ResponseEntity with
* status code 201 - Created but without ResponseBody. In any
* failure the JsonResponseExceptionHandler is handling the
* response.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetsRest> createDistributionSets(
@RequestBody final List<DistributionSetRequestBodyPost> sets);
/**
* Handles the DELETE request for a single DistributionSet .
*
* @param distributionSetId
* the ID of the DistributionSet to delete
* @return status OK if delete as successful.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}")
public ResponseEntity<Void> deleteDistributionSet(@PathVariable("distributionSetId") final Long distributionSetId);
/**
* Handles the UPDATE request for a single DistributionSet .
*
* @param distributionSetId
* the ID of the DistributionSet to delete
* @param toUpdate
* with the data that needs updating
*
* @return status OK if update as successful with updated content.
*
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<DistributionSetRest> updateDistributionSet(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestBody final DistributionSetRequestBodyPut toUpdate);
/**
* Handles the GET request of retrieving assigned targets to a specific
* distribution set.
*
* @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 parameter in the request URL, syntax
* {@code q=name==abc}
* @return status OK if get request is successful with the paged list of
* targets
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedTargets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getAssignedTargets(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving installed targets to a specific
* distribution set.
*
* @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 parameter in the request URL, syntax
* {@code q=name==abc}
* @return status OK if get request is successful with the paged list of
* targets
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/installedTargets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getInstalledTargets(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the POST request of assigning multiple targets to a single
* distribution set.
*
* @param distributionSetId
* the ID of the distribution set within the URL path parameter
* @param targetIds
* the IDs of the target which should get assigned to the
* distribution set given in the response body
* @return status OK if the assignment of the targets was successful and a
* complex return body which contains information about the assigned
* targets and the already assigned targets counters
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedTargets", consumes = {
"application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetAssignmentResponseBody> createAssignedTarget(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestBody final List<TargetAssignmentRequestBody> targetIds);
/**
* Gets a paged list of meta data for a distribution set.
*
* @param distributionSetId
* the ID of the distribution set for the meta data
* @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=key==abc}
* @return status OK if get request is successful with the paged list of
* meta data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRestPageList> getMetadata(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Gets a single meta data value for a specific key of a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to get the meta data from
* @param metadataKey
* the key of the meta data entry to retrieve the value from
* @return status OK if get request is successful with the value of the meta
* data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MetadataRest> getMetadataValue(
@PathVariable("distributionSetId") final Long distributionSetId,
@PathVariable("metadataKey") final String metadataKey);
/**
* Updates a single meta data value of a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to update the meta data entry
* @param metadataKey
* the key of the meta data to update the value
* @return status OK if the update request is successful and the updated
* meta data result
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRest> updateMetadata(@PathVariable("distributionSetId") final Long distributionSetId,
@PathVariable("metadataKey") final String metadataKey, @RequestBody final MetadataRest metadata);
/**
* Deletes a single meta data entry from the distribution set.
*
* @param distributionSetId
* the ID of the distribution set to delete the meta data entry
* @param metadataKey
* the key of the meta data to delete
* @return status OK if the delete request is successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/metadata/{metadataKey}")
public ResponseEntity<Void> deleteMetadata(@PathVariable("distributionSetId") final Long distributionSetId,
@PathVariable("metadataKey") final String metadataKey);
/**
* Creates a list of meta data for a specific distribution set.
*
* @param distributionSetId
* the ID of the distribution set to create meta data for
* @param metadataRest
* the list of meta data entries to create
* @return status created if post request is successful with the value of
* the created meta data
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/metadata", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<List<MetadataRest>> createMetadata(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestBody final List<MetadataRest> metadataRest);
/**
* Assigns a list of software modules to a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to assign software modules for
* @param softwareModuleIDs
* the list of software modules ids to assign
* @return http status
*
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedSM", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> assignSoftwareModules(@PathVariable("distributionSetId") final Long distributionSetId,
@RequestBody final List<SoftwareModuleAssigmentRest> softwareModuleIDs);
/**
* Deletes the assignment of the software module form the distribution set.
*
* @param distributionSetId
* the ID of the distribution set to reject the software module
* for
* @param softwareModuleId
* the software module id to get rejected form the distribution
* set
* @return status OK if rejection was successful.
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/assignedSM/{softwareModuleId}")
public ResponseEntity<Void> deleteAssignSoftwareModules(
@PathVariable("distributionSetId") final Long distributionSetId,
@PathVariable("softwareModuleId") final Long softwareModuleId);
/**
* Handles the GET request for retrieving the assigned software modules of a
* specific distribution set.
*
* @param distributionSetId
* the ID of the distribution to retrieve
* @param pagingOffsetParam
* the offset of list of sets 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}
* @return a list of the assigned software modules of a distribution set
* with status OK, if none is assigned than {@code null}
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedSM", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModulePagedList> getAssignedSoftwareModules(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam);
}

View File

@@ -0,0 +1,215 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
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;
/**
* REST Resource handling for DistributionSetTag CRUD operations.
*
*/
@RequestMapping(RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING)
public interface DistributionSetTagRestApi {
/**
* Handles the GET request of retrieving all DistributionSet tags.
*
* @param pagingOffsetParam
* the offset of list of DistributionSet tags 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 target tags 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 })
public ResponseEntity<TagPagedList> getDistributionSetTags(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
*
* @return a single distribution set tag with status OK.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionsetTagId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> getDistributionSetTag(
@PathVariable("distributionsetTagId") final Long distributionsetTagId);
/**
* Handles the POST request of creating new distribution set tag. The
* request body must always be a list of tags.
*
* @param tags
* the distribution set tags to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created. The Response Body are the created
* distribution set tags but without ResponseBody.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagsRest> createDistributionSetTags(@RequestBody final List<TagRequestBodyPut> tags);
/**
*
* Handles the PUT request of updating a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @param restDSTagRest
* the the request body to be updated
* @return status OK if update is successful and the updated distribution
* set tag.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionsetTagId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> updateDistributionSetTag(
@PathVariable("distributionsetTagId") final Long distributionsetTagId,
@RequestBody final TagRequestBodyPut restDSTagRest);
/**
* Handles the DELETE request for a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @return status OK if delete as successfully.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionsetTagId}")
public ResponseEntity<Void> deleteDistributionSetTag(
@PathVariable("distributionsetTagId") final Long distributionsetTagId);
/**
* Handles the GET request of retrieving all assigned distribution sets by
* the given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag
*
* @return the list of assigned distribution sets.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.GET, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<DistributionSetsRest> getAssignedDistributionSets(
@PathVariable("distributionsetTagId") final Long distributionsetTagId);
/**
* Handles the POST request to toggle the assignment of distribution sets by
* the given tag id.
*
* @param distributionsetTagIds
* the ID of the distribution set tag to retrieve
* @param assignedDSRequestBodies
* list of distribution set ids to be toggled
*
* @return the list of assigned distribution sets and unassigned
* distribution sets.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING
+ "/toggleTagAssignment")
public ResponseEntity<DistributionSetTagAssigmentResultRest> toggleTagAssignment(
@PathVariable("distributionsetTagId") final Long distributionsetTagId,
@RequestBody final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies);
/**
* Handles the POST request to assign distribution sets to the given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
* @param assignedDSRequestBodies
* list of distribution sets ids to be assigned
*
* @return the list of assigned distribution set.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<DistributionSetsRest> assignDistributionSets(
@PathVariable("distributionsetTagId") final Long distributionsetTagId,
@RequestBody final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies);
/**
* Handles the DELETE request to unassign all distribution set from the
* given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<Void> unassignDistributionSets(
@PathVariable("distributionsetTagId") final Long distributionsetTagId);
/**
* Handles the DELETE request to unassign one distribution set from the
* given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @param distributionsetId
* the ID of the distribution set to unassign
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING
+ "/{distributionsetId}")
public ResponseEntity<Void> unassignDistributionSet(
@PathVariable("distributionsetTagId") final Long distributionsetTagId,
@PathVariable("distributionsetId") final Long distributionsetId);
}

View File

@@ -0,0 +1,259 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.IdRest;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypePagedList;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRest;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypesRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest;
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;
/**
* REST Resource handling for SoftwareModule and related Artifact CRUD
* operations.
*
*/
@RequestMapping(RestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING)
public interface DistributionSetTypeRestApi {
/**
* Handles the GET request of retrieving all DistributionSetTypes.
*
* @param pagingOffsetParam
* the offset of list of modules 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 DistributionSetType 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 })
public ResponseEntity<DistributionSetTypePagedList> getDistributionSetTypes(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single DistributionSetType
* within.
*
* @param distributionSetTypeId
* the ID of the module type to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetTypeRest> getDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId);
/**
* Handles the DELETE request for a single Distribution Set Type.
*
* @param distributionSetTypeId
* the ID of the module to retrieve
* @return status OK if delete as sucessfull.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}")
public ResponseEntity<Void> deleteDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId);
/**
* Handles the PUT request of updating a Distribution Set Type.
*
* @param distributionSetTypeId
* the ID of the software module in the URL
* @param restDistributionSetType
* the module type to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetTypeId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetTypeRest> updateDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@RequestBody final DistributionSetTypeRequestBodyPut restDistributionSetType);
/**
* Handles the POST request of creating new DistributionSetTypes. The
* request body must always be a list of types.
*
* @param distributionSetTypes
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
public ResponseEntity<DistributionSetTypesRest> createDistributionSetTypes(
@RequestBody final List<DistributionSetTypeRequestBodyPost> distributionSetTypes);
/**
* Handles the GET request of retrieving the list of mandatory software
* module types in that distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypesRest> getMandatoryModules(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId);
/**
* Handles the GET request of retrieving the single mandatory software
* module type in that distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param softwareModuleTypeId
* of SoftwareModuleType.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> getMandatoryModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles the GET request of retrieving the single optional software module
* type in that distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param softwareModuleTypeId
* of SoftwareModuleType.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> getOptionalModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles the GET request of retrieving the list of optional software
* module types in that distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypesRest> getOptionalModules(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId);
/**
* Handles DELETE request for removing a mandatory module from the
* DistributionSetType.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param softwareModuleTypeId
* of the SoftwareModuleType to remove
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> removeMandatoryModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles DELETE request for removing an optional module from the
* DistributionSetType.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param softwareModuleTypeId
* of the SoftwareModuleType to remove
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> removeOptionalModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles the POST request for adding a mandatory software module type to a
* distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param smtId
* of the SoftwareModuleType to add
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> addMandatoryModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final IdRest smtId);
/**
* Handles the POST request for adding an optional software module type to a
* distribution set type.
*
* @param distributionSetTypeId
* of the DistributionSetType.
* @param smtId
* of the SoftwareModuleType to add
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> addOptionalModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final IdRest smtId);
}

View File

@@ -0,0 +1,209 @@
/**
* 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.rest.resource.api;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutPagedList;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody;
import org.eclipse.hawkbit.rest.resource.model.rolloutgroup.RolloutGroupPagedList;
import org.eclipse.hawkbit.rest.resource.model.rolloutgroup.RolloutGroupResponseBody;
import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList;
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;
/**
* REST Resource handling rollout CRUD operations.
*
*/
@RequestMapping(RestConstants.ROLLOUT_V1_REQUEST_MAPPING)
public interface RolloutRestApi {
/**
* Handles the GET request of retrieving all rollouts.
*
* @param pagingOffsetParam
* the offset of list of rollouts 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 rollouts 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 = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutPagedList> getRollouts(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single rollout.
*
* @param rolloutId
* the ID of the rollout to retrieve
* @return a single rollout with status OK.
* @throws EntityNotFoundException
* in case no rollout with the given {@code rolloutId} exists.
*/
@RequestMapping(value = "/{rolloutId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" })
public ResponseEntity<RolloutResponseBody> getRollout(@PathVariable("rolloutId") final Long rolloutId);
/**
* Handles the POST request for creating rollout.
*
* @param rollout
* the rollout body to be created.
* @return In case rollout could successful created the ResponseEntity with
* status code 201 with the successfully created rollout. In any
* failure the JsonResponseExceptionHandler is handling the
* response.
* @throws EntityNotFoundException
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<RolloutResponseBody> create(@RequestBody final RolloutRestRequestBody rolloutRequestBody);
/**
* Handles the POST request for starting a rollout.
*
* @param rolloutId
* the ID of the rollout to be started.
* @return OK response (200) if rollout could be started. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#startRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/start", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> start(@PathVariable("rolloutId") final Long rolloutId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_ASYNC, defaultValue = "false") final boolean startAsync);
/**
* Handles the POST request for pausing a rollout.
*
* @param rolloutId
* the ID of the rollout to be paused.
* @return OK response (200) if rollout could be paused. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#pauseRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/pause", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> pause(@PathVariable("rolloutId") final Long rolloutId);
/**
* Handles the POST request for resuming a rollout.
*
* @param rolloutId
* the ID of the rollout to be resumed.
* @return OK response (200) if rollout could be resumed. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#resumeRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/resume", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> resume(@PathVariable("rolloutId") final Long rolloutId);
/**
* Handles the GET request of retrieving all rollout groups referred to a
* rollout.
*
* @param pagingOffsetParam
* the offset of list of rollout groups 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 rollout groups referred to a rollout 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, value = "/{rolloutId}/deploygroups", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutGroupPagedList> getRolloutGroups(@PathVariable("rolloutId") final Long rolloutId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request for retrieving a single rollout group.
*
* @param rolloutId
* the rolloutId to retrieve the group from
* @param groupId
* the groupId to retrieve the rollout group
* @return the OK response containing the RolloutGroupResponseBody
* @throws EntityNotFoundException
*/
@RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutGroupResponseBody> getRolloutGroup(@PathVariable("rolloutId") final Long rolloutId,
@PathVariable("groupId") final Long groupId);
/**
* Retrieves all targets related to a specific rollout group.
*
* @param rolloutId
* the ID of the rollout
* @param groupId
* the ID of the rollout group
* @param pagingOffsetParam
* the offset of list of rollout groups 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 paged list of targets related to a specific rollout and rollout
* group.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}/targets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId,
@PathVariable("groupId") final Long groupId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
}

View File

@@ -0,0 +1,289 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactsRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulePagedList;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest;
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;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
/**
* REST Resource handling for SoftwareModule and related Artifact CRUD
* operations.
*
*/
@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
public interface SoftwareModuleRestAPI {
/**
* Handles POST request for artifact upload.
*
* @param softwareModuleId
* of the parent SoftwareModule
* @param file
* that has to be uploaded
* @param optionalFileName
* to override {@link MultipartFile#getOriginalFilename()}
* @param md5Sum
* checksum for uploaded content check
* @param sha1Sum
* checksum for uploaded content check
*
* @return In case all sets could successful be created the ResponseEntity
* with status code 201 - Created but without ResponseBody. In any
* failure the JsonResponseExceptionHandler is handling the
* response.
*/
@RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/artifacts", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ArtifactRest> uploadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestParam("file") final MultipartFile file,
@RequestParam(value = "filename", required = false) final String optionalFileName,
@RequestParam(value = "md5sum", required = false) final String md5Sum,
@RequestParam(value = "sha1sum", required = false) final String sha1Sum);
/**
* Handles the GET request of retrieving all meta data of artifacts assigned
* to a software module.
*
* @param softwareModuleId
* of the parent SoftwareModule
*
* @return a list of all artifacts 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, value = "/{softwareModuleId}/artifacts", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
public ResponseEntity<ArtifactsRest> getArtifacts(@PathVariable("softwareModuleId") final Long softwareModuleId);
/**
* Handles the GET request of retrieving a single Artifact meta data
* request.
*
* @param softwareModuleId
* of the parent SoftwareModule
* @param artifactId
* of the related LocalArtifact
*
* @return responseEntity with status ok if successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
public ResponseEntity<ArtifactRest> getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId);
/**
* Handles the DELETE request for a single SoftwareModule.
*
* @param softwareModuleId
* the ID of the module that has the artifact
* @param artifactId
* of the artifact to be deleted
*
* @return status OK if delete as successful.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/artifacts/{artifactId}")
@ResponseBody
public ResponseEntity<Void> deleteArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId);
/**
* Handles the GET request of retrieving all softwaremodules.
*
* @param pagingOffsetParam
* the offset of list of modules 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 modules 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 })
public ResponseEntity<SoftwareModulePagedList> getSoftwareModules(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single software module.
*
* @param softwareModuleId
* the ID of the module to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleRest> getSoftwareModule(
@PathVariable("softwareModuleId") final Long softwareModuleId);
/**
* Handles the POST request of creating new softwaremodules. The request
* body must always be a list of modules.
*
* @param softwareModules
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
public ResponseEntity<SoftwareModulesRest> createSoftwareModules(
@RequestBody final List<SoftwareModuleRequestBodyPost> softwareModules);
/**
* Handles the PUT request of updating a software module.
*
* @param softwareModuleId
* the ID of the software module in the URL
* @param restSoftwareModule
* the modules to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleRest> updateSoftwareModule(
@PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestBody final SoftwareModuleRequestBodyPut restSoftwareModule);
/**
* Handles the DELETE request for a single softwaremodule.
*
* @param softwareModuleId
* the ID of the module to retrieve
* @return status OK if delete as sucessfull.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}")
public ResponseEntity<Void> deleteSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId);
/**
* Gets a paged list of meta data for a software module.
*
* @param softwareModuleId
* the ID of the software module for the meta data
* @param pagingOffsetParam
* the offset of list of meta data 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=key==abc}
* @return status OK if get request is successful with the paged list of
* meta data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRestPageList> getMetadata(
@PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Gets a single meta data value for a specific key of a software module.
*
* @param softwareModuleId
* the ID of the software module to get the meta data from
* @param metadataKey
* the key of the meta data entry to retrieve the value from
* @return status OK if get request is successful with the value of the meta
* data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MetadataRest> getMetadataValue(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey);
/**
* Updates a single meta data value of a software module.
*
* @param softwareModuleId
* the ID of the software module to update the meta data entry
* @param metadataKey
* the key of the meta data to update the value
* @return status OK if the update request is successful and the updated
* meta data result
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRest> updateMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey, @RequestBody final MetadataRest metadata);
/**
* Deletes a single meta data entry from the software module.
*
* @param softwareModuleId
* the ID of the software module to delete the meta data entry
* @param metadataKey
* the key of the meta data to delete
* @return status OK if the delete request is successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/metadata/{metadataKey}")
public ResponseEntity<Void> deleteMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey);
/**
* Creates a list of meta data for a specific software module.
*
* @param softwareModuleId
* the ID of the distribution set to create meta data for
* @param metadataRest
* the list of meta data entries to create
* @return status created if post request is successful with the value of
* the created meta data
*/
@RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/metadata", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<List<MetadataRest>> createMetadata(
@PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestBody final List<MetadataRest> metadataRest);
}

View File

@@ -0,0 +1,119 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypePagedList;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest;
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;
/**
* REST Resource handling for SoftwareModule and related Artifact CRUD
* operations.
*
*/
@RequestMapping(RestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING)
public interface SoftwareModuleTypeRestApi {
/**
* Handles the GET request of retrieving all SoftwareModuleTypes .
*
* @param pagingOffsetParam
* the offset of list of modules 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 module type 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 })
public ResponseEntity<SoftwareModuleTypePagedList> getTypes(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single software module type .
*
* @param softwareModuleTypeId
* the ID of the module type to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleTypeId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> getSoftwareModuleType(
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles the DELETE request for a single software module type .
*
* @param softwareModuleTypeId
* the ID of the module to retrieve
* @return status OK if delete as successfully.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleTypeId}")
public ResponseEntity<Void> deleteSoftwareModuleType(
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId);
/**
* Handles the PUT request of updating a software module type .
*
* @param softwareModuleTypeId
* the ID of the software module in the URL
* @param restSoftwareModuleType
* the module type to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleTypeId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> updateSoftwareModuleType(
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId,
@RequestBody final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType);
/**
* Handles the POST request of creating new SoftwareModuleTypes. The request
* body must always be a list of types.
*
* @param softwareModuleTypes
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
public ResponseEntity<SoftwareModuleTypesRest> createSoftwareModuleTypes(
@RequestBody final List<SoftwareModuleTypeRequestBodyPost> softwareModuleTypes);
}

View File

@@ -0,0 +1,284 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.action.ActionPagedList;
import org.eclipse.hawkbit.rest.resource.model.action.ActionRest;
import org.eclipse.hawkbit.rest.resource.model.action.ActionStatusPagedList;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest;
import org.eclipse.hawkbit.rest.resource.model.target.DistributionSetAssigmentRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetAttributes;
import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.target.TargetRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
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(RestConstants.TARGET_V1_REQUEST_MAPPING)
public interface TargetRestApi {
/**
* Handles the GET request of retrieving a single target.
*
* @param targetId
* the ID of the target to retrieve
* @return a single target with status OK.
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetRest> getTarget(@PathVariable("targetId") final String targetId);
/**
* Handles the GET request of retrieving all 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 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 })
public ResponseEntity<TargetPagedList> getTargets(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the POST request of creating new targets. The request body must
* always be a list of targets.
*
* @param targets
* the targets to be created.
* @return In case all targets could successful created the ResponseEntity
* with status code 201 with a list of successfully created
* entities. 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 })
public ResponseEntity<TargetsRest> createTargets(@RequestBody final List<TargetRequestBody> targets);
/**
* Handles the PUT request of updating a target. 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 targetId
* the path parameter which contains the ID of the target
* @param targetRest
* the request body which contains the fields which should be
* updated, fields which are not given are ignored for the
* udpate.
* @return the updated target response which contains all fields also fields
* which have not updated
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{targetId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetRest> updateTarget(@PathVariable("targetId") final String targetId,
@RequestBody final TargetRequestBody targetRest);
/**
* Handles the DELETE request of deleting a target.
*
* @param targetId
* the ID of the target to be deleted
* @return If the given targetId could exists and could be deleted Http OK.
* In any failure the JsonResponseExceptionHandler is handling the
* response.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> deleteTarget(@PathVariable("targetId") final String targetId);
/**
* Handles the GET request of retrieving the attributes of a specific
* target.
*
* @param targetId
* the ID of the target to retrieve the attributes.
* @return the target attributes as map response with status OK
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/attributes", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetAttributes> getAttributes(@PathVariable("targetId") final String targetId);
/**
* Handles the GET request of retrieving the Actions of a specific target.
*
* @param targetId
* to load actions for
* @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=status==pending}
* @return a list of all Actions 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, value = "/{targetId}/actions", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionPagedList> getActionHistory(@PathVariable("targetId") final String targetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a specific Actions of a specific
* Target.
*
* @param targetId
* to load the action for
* @param actionId
* to load
* @return the action
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionRest> getAction(@PathVariable("targetId") final String targetId,
@PathVariable("actionId") final Long actionId);
/**
* Handles the DELETE request of canceling an specific Actions of a specific
* Target.
*
* @param targetId
* the ID of the target in the URL path parameter
* @param actionId
* the ID of the action in the URL path parameter
* @param force
* optional parameter, which indicates a force cancel
* @return status no content in case cancellation was successful
* @throws CancelActionNotAllowedException
* if the given action is not active and cannot be canceled.
* @throws EntityNotFoundException
* if the target or the action is not found
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}/actions/{actionId}")
public ResponseEntity<Void> cancelAction(@PathVariable("targetId") final String targetId,
@PathVariable("actionId") final Long actionId,
@RequestParam(value = "force", required = false, defaultValue = "false") final boolean force);
/**
* Handles the GET request of retrieving the ActionStatus of a specific
* target and action.
*
* @param targetId
* of the the action
* @param actionId
* of the status we are intend to load
* @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}
* @return a list of all ActionStatus 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, value = "/{targetId}/actions/{actionId}/status", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionStatusPagedList> getActionStatusList(@PathVariable("targetId") final String targetId,
@PathVariable("actionId") final Long actionId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam);
/**
* Handles the GET request of retrieving the assigned distribution set of an
* specific target.
*
* @param targetId
* 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. "{}")
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/assignedDS", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getAssignedDistributionSet(
@PathVariable("targetId") final String targetId);
/**
* Changes the assigned distribution set of a target.
*
* @param targetId
* of the target to change
* @param dsId
* of the distributionset that is to be assigned
* @return http status
*
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*
*/
@RequestMapping(method = RequestMethod.POST, value = "/{targetId}/assignedDS", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> postAssignedDistributionSet(@PathVariable("targetId") final String targetId,
@RequestBody final DistributionSetAssigmentRest dsId);
/**
* Handles the GET request of retrieving the installed distribution set of
* an specific target.
*
* @param targetId
* the ID of the target to retrieve
* @return the assigned installed set with status OK, if none is installed
* than {@code null} content (e.g. "{}")
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/installedDS", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getInstalledDistributionSet(
@PathVariable("targetId") final String targetId);
}

View File

@@ -0,0 +1,196 @@
/**
* 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.rest.resource.api;
import java.util.List;
import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest;
import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest;
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;
/**
* REST Resource handling for TargetTag CRUD operations.
*
*/
@RequestMapping(RestConstants.TARGET_TAG_V1_REQUEST_MAPPING)
public interface TargetTagRestApi {
/**
* Handles the GET request of retrieving all target tags.
*
* @param pagingOffsetParam
* the offset of list of target tags 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 target tags 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 })
public ResponseEntity<TagPagedList> getTargetTags(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam);
/**
* Handles the GET request of retrieving a single target tag.
*
* @param targetTagId
* the ID of the target tag to retrieve
*
* @return a single target tag with status OK.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetTagId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> getTargetTag(@PathVariable("targetTagId") final Long targetTagId);
/**
* Handles the POST request of creating new target tag. The request body
* must always be a list of tags.
*
* @param tags
* the target tags to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created. The Response Body are the created
* target tags but without ResponseBody.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagsRest> createTargetTags(@RequestBody final List<TagRequestBodyPut> tags);
/**
*
* Handles the PUT request of updating a single targetr tag.
*
* @param targetTagId
* the ID of the target tag
* @param restTargetTagRest
* the the request body to be updated
* @return status OK if update is successful and the updated target tag.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{targetTagId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> updateTagretTag(@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final TagRequestBodyPut restTargetTagRest);
/**
* Handles the DELETE request for a single target tag.
*
* @param targetTagId
* the ID of the target tag
* @return status OK if delete as successfully.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetTagId}")
public ResponseEntity<Void> deleteTargetTag(@PathVariable("targetTagId") final Long targetTagId);
/**
* Handles the GET request of retrieving all assigned targets by the given
* tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
*
* @return the list of assigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.GET, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<TargetsRest> getAssignedTargets(@PathVariable("targetTagId") final Long targetTagId);
/**
* Handles the POST request to toggle the assignment of targets by the given
* tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be toggled
*
* @return the list of assigned targets and unassigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING
+ "/toggleTagAssignment")
public ResponseEntity<TargetTagAssigmentResultRest> toggleTagAssignment(
@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final List<AssignedTargetRequestBody> assignedTargetRequestBodies);
/**
* Handles the POST request to assign targets to the given tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be assigned
*
* @return the list of assigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<TargetsRest> assignTargets(@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final List<AssignedTargetRequestBody> assignedTargetRequestBodies);
/**
* Handles the DELETE request to unassign all targets from the given tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<Void> unassignTargets(@PathVariable("targetTagId") final Long targetTagId);
/**
* Handles the DELETE request to unassign one target from the given tag id.
*
* @param targetTagId
* the ID of the target tag
* @param controllerId
* the ID of the target to unassign
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING
+ "/{controllerId}")
public ResponseEntity<Void> unassignTarget(@PathVariable("targetTagId") final Long targetTagId,
@PathVariable("controllerId") final String controllerId);
}

View File

@@ -22,6 +22,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest;
@@ -169,13 +171,13 @@ public final class DistributionSetMapper {
response.setRequiredMigrationStep(distributionSet.isRequiredMigrationStep());
response.add(
linkTo(methodOn(DistributionSetResource.class).getDistributionSet(response.getDsId())).withRel("self"));
linkTo(methodOn(DistributionSetRestApi.class).getDistributionSet(response.getDsId())).withRel("self"));
response.add(linkTo(
methodOn(DistributionSetTypeResource.class).getDistributionSetType(distributionSet.getType().getId()))
methodOn(DistributionSetTypeRestApi.class).getDistributionSetType(distributionSet.getType().getId()))
.withRel("type"));
response.add(linkTo(methodOn(DistributionSetResource.class).getMetadata(response.getDsId(),
response.add(linkTo(methodOn(DistributionSetRestApi.class).getMetadata(response.getDsId(),
Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET),
Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, null))
.withRel("metadata"));

View File

@@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList;
@@ -51,25 +52,14 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
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;
import org.springframework.web.bind.annotation.RestController;
/**
* REST Resource handling for {@link DistributionSet} CRUD operations.
*
*
*
*
*/
@RestController
@RequestMapping(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
public class DistributionSetResource {
public class DistributionSetResource implements DistributionSetRestApi {
private static final Logger LOG = LoggerFactory.getLogger(DistributionSetResource.class);
@Autowired
@@ -90,32 +80,9 @@ public class DistributionSetResource {
@Autowired
private DistributionSetManagement distributionSetManagement;
/**
* Handles the GET request of retrieving all {@link DistributionSet}s within
* SP.
*
* @param pagingOffsetParam
* the offset of list of sets 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 set 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 })
public ResponseEntity<DistributionSetPagedList> getDistributionSets(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<DistributionSetPagedList> getDistributionSets(final int pagingOffsetParam,
final int pagingLimitParam, final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -124,99 +91,51 @@ public class DistributionSetResource {
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<DistributionSet> findDsPage;
if (rsqlParam != null) {
findDsPage = distributionSetManagement.findDistributionSetsAll(
findDsPage = this.distributionSetManagement.findDistributionSetsAll(
RSQLUtility.parse(rsqlParam, DistributionSetFields.class), pageable, false);
} else {
findDsPage = distributionSetManagement.findDistributionSetsAll(pageable, false, null);
findDsPage = this.distributionSetManagement.findDistributionSetsAll(pageable, false, null);
}
final List<DistributionSetRest> rest = DistributionSetMapper.toResponseFromDsList(findDsPage.getContent());
return new ResponseEntity<>(new DistributionSetPagedList(rest, findDsPage.getTotalElements()), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single {@link DistributionSet}
* within SP.
*
* @param distributionSetId
* the ID of the set to retrieve
*
* @return a single {@link DistributionSet} with status OK.
*
* @throws EntityNotFoundException
* in case no {@link DistributionSet} with the given ID exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getDistributionSet(@PathVariable final Long distributionSetId) {
@Override
public ResponseEntity<DistributionSetRest> getDistributionSet(final Long distributionSetId) {
final DistributionSet foundDs = findDistributionSetWithExceptionIfNotFound(distributionSetId);
return new ResponseEntity<>(DistributionSetMapper.toResponse(foundDs), HttpStatus.OK);
}
/**
* Handles the POST request of creating new distribution sets within SP. The
* request body must always be a list of sets. The requests is delegating to
* the {@link SoftwareManagement#createDistributionSet(DistributionSet))}.
*
* @param sets
* the {@link DistributionSet}s to be created.
* @return In case all sets could successful created the ResponseEntity with
* status code 201 - Created but without ResponseBody. In any
* failure the JsonResponseExceptionHandler is handling the
* response.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<DistributionSetsRest> createDistributionSets(
@RequestBody final List<DistributionSetRequestBodyPost> sets) {
final List<DistributionSetRequestBodyPost> sets) {
LOG.debug("creating {} distribution sets", sets.size());
// set default Ds type if ds type is null
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(
systemManagement.getTenantMetadata(currentTenant.getCurrentTenant()).getDefaultDsType().getKey()));
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(this.systemManagement
.getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey()));
final Iterable<DistributionSet> createdDSets = distributionSetManagement.createDistributionSets(
DistributionSetMapper.dsFromRequest(sets, softwareManagement, distributionSetManagement));
final Iterable<DistributionSet> createdDSets = this.distributionSetManagement.createDistributionSets(
DistributionSetMapper.dsFromRequest(sets, this.softwareManagement, this.distributionSetManagement));
LOG.debug("{} distribution sets created, return status {}", sets.size(), HttpStatus.CREATED);
return new ResponseEntity<>(DistributionSetMapper.toResponseDistributionSets(createdDSets), HttpStatus.CREATED);
}
/**
* Handles the DELETE request for a single {@link DistributionSet} within
* SP.
*
* @param distributionSetId
* the ID of the {@link DistributionSet} to delete
* @return status OK if delete as successful.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}")
public ResponseEntity<Void> deleteDistributionSet(@PathVariable final Long distributionSetId) {
@Override
public ResponseEntity<Void> deleteDistributionSet(final Long distributionSetId) {
final DistributionSet set = findDistributionSetWithExceptionIfNotFound(distributionSetId);
distributionSetManagement.deleteDistributionSet(set);
this.distributionSetManagement.deleteDistributionSet(set);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the UPDATE request for a single {@link DistributionSet} within
* SP.
*
* @param distributionSetId
* the ID of the {@link DistributionSet} to delete
* @param toUpdate
* with the data that needs updating
*
* @return status OK if update as successful with updated content.
*
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<DistributionSetRest> updateDistributionSet(@PathVariable final Long distributionSetId,
@RequestBody final DistributionSetRequestBodyPut toUpdate) {
@Override
public ResponseEntity<DistributionSetRest> updateDistributionSet(final Long distributionSetId,
final DistributionSetRequestBodyPut toUpdate) {
final DistributionSet set = findDistributionSetWithExceptionIfNotFound(distributionSetId);
if (toUpdate.getDescription() != null) {
@@ -231,38 +150,13 @@ public class DistributionSetResource {
set.setVersion(toUpdate.getVersion());
}
return new ResponseEntity<>(
DistributionSetMapper.toResponse(distributionSetManagement.updateDistributionSet(set)), HttpStatus.OK);
DistributionSetMapper.toResponse(this.distributionSetManagement.updateDistributionSet(set)),
HttpStatus.OK);
}
/**
* Handles the GET request of retrieving assigned targets to a specific
* distribution set.
*
* @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 parameter in the request URL, syntax
* {@code q=name==abc}
* @return status OK if get request is successful with the paged list of
* targets
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedTargets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getAssignedTargets(@PathVariable final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TargetPagedList> getAssignedTargets(final Long distributionSetId, final int pagingOffsetParam,
final int pagingLimitParam, final String sortParam, final String rsqlParam) {
// check if distribution set exists otherwise throw exception
// immediately
@@ -275,45 +169,19 @@ public class DistributionSetResource {
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<Target> targetsAssignedDS;
if (rsqlParam != null) {
targetsAssignedDS = targetManagement.findTargetByAssignedDistributionSet(distributionSetId,
targetsAssignedDS = this.targetManagement.findTargetByAssignedDistributionSet(distributionSetId,
RSQLUtility.parse(rsqlParam, TargetFields.class), pageable);
} else {
targetsAssignedDS = targetManagement.findTargetByAssignedDistributionSet(distributionSetId, pageable);
targetsAssignedDS = this.targetManagement.findTargetByAssignedDistributionSet(distributionSetId, pageable);
}
return new ResponseEntity<>(new TargetPagedList(TargetMapper.toResponse(targetsAssignedDS.getContent()),
targetsAssignedDS.getTotalElements()), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving installed targets to a specific
* distribution set.
*
* @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 parameter in the request URL, syntax
* {@code q=name==abc}
* @return status OK if get request is successful with the paged list of
* targets
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/installedTargets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getInstalledTargets(@PathVariable final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TargetPagedList> getInstalledTargets(final Long distributionSetId,
final int pagingOffsetParam, final int pagingLimitParam, final String sortParam, final String rsqlParam) {
// check if distribution set exists otherwise throw exception
// immediately
findDistributionSetWithExceptionIfNotFound(distributionSetId);
@@ -325,36 +193,22 @@ public class DistributionSetResource {
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<Target> targetsInstalledDS;
if (rsqlParam != null) {
targetsInstalledDS = targetManagement.findTargetByInstalledDistributionSet(distributionSetId,
targetsInstalledDS = this.targetManagement.findTargetByInstalledDistributionSet(distributionSetId,
RSQLUtility.parse(rsqlParam, TargetFields.class), pageable);
} else {
targetsInstalledDS = targetManagement.findTargetByInstalledDistributionSet(distributionSetId, pageable);
targetsInstalledDS = this.targetManagement.findTargetByInstalledDistributionSet(distributionSetId,
pageable);
}
return new ResponseEntity<>(new TargetPagedList(TargetMapper.toResponse(targetsInstalledDS.getContent()),
targetsInstalledDS.getTotalElements()), HttpStatus.OK);
}
/**
* Handles the POST request of assigning multiple targets to a single
* distribution set.
*
* @param distributionSetId
* the ID of the distribution set within the URL path parameter
* @param targetIds
* the IDs of the target which should get assigned to the
* distribution set given in the response body
* @return status OK if the assignment of the targets was successful and a
* complex return body which contains information about the assigned
* targets and the already assigned targets counters
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedTargets", consumes = {
"application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetAssignmentResponseBody> createAssignedTarget(@PathVariable final Long distributionSetId,
@RequestBody final List<TargetAssignmentRequestBody> targetIds) {
@Override
public ResponseEntity<TargetAssignmentResponseBody> createAssignedTarget(final Long distributionSetId,
final List<TargetAssignmentRequestBody> targetIds) {
final DistributionSetAssignmentResult assignDistributionSet = deployManagament.assignDistributionSet(
final DistributionSetAssignmentResult assignDistributionSet = this.deployManagament.assignDistributionSet(
distributionSetId,
targetIds.stream()
.map(t -> new TargetWithActionType(t.getId(),
@@ -364,33 +218,9 @@ public class DistributionSetResource {
return new ResponseEntity<>(DistributionSetMapper.toResponse(assignDistributionSet), HttpStatus.OK);
}
/**
* Gets a paged list of meta data for a distribution set.
*
* @param distributionSetId
* the ID of the distribution set for the meta data
* @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=key==abc}
* @return status OK if get request is successful with the paged list of
* meta data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRestPageList> getMetadata(@PathVariable final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<MetadataRestPageList> getMetadata(final Long distributionSetId, final int pagingOffsetParam,
final int pagingLimitParam, final String sortParam, final String rsqlParam) {
// check if distribution set exists otherwise throw exception
// immediately
@@ -404,11 +234,11 @@ public class DistributionSetResource {
final Page<DistributionSetMetadata> metaDataPage;
if (rsqlParam != null) {
metaDataPage = distributionSetManagement.findDistributionSetMetadataByDistributionSetId(distributionSetId,
RSQLUtility.parse(rsqlParam, DistributionSetMetadataFields.class), pageable);
metaDataPage = this.distributionSetManagement.findDistributionSetMetadataByDistributionSetId(
distributionSetId, RSQLUtility.parse(rsqlParam, DistributionSetMetadataFields.class), pageable);
} else {
metaDataPage = distributionSetManagement.findDistributionSetMetadataByDistributionSetId(distributionSetId,
pageable);
metaDataPage = this.distributionSetManagement
.findDistributionSetMetadataByDistributionSetId(distributionSetId, pageable);
}
return new ResponseEntity<>(
@@ -418,119 +248,59 @@ public class DistributionSetResource {
}
/**
* Gets a single meta data value for a specific key of a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to get the meta data from
* @param metadataKey
* the key of the meta data entry to retrieve the value from
* @return status OK if get request is successful with the value of the meta
* data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MetadataRest> getMetadataValue(@PathVariable final Long distributionSetId,
@PathVariable final String metadataKey) {
@Override
public ResponseEntity<MetadataRest> getMetadataValue(final Long distributionSetId, final String metadataKey) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
final DistributionSetMetadata findOne = distributionSetManagement
final DistributionSetMetadata findOne = this.distributionSetManagement
.findOne(new DsMetadataCompositeKey(ds, metadataKey));
return ResponseEntity.<MetadataRest> ok(DistributionSetMapper.toResponseDsMetadata(findOne));
}
/**
* Updates a single meta data value of a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to update the meta data entry
* @param metadataKey
* the key of the meta data to update the value
* @return status OK if the update request is successful and the updated
* meta data result
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<MetadataRest> updateMetadata(@PathVariable final Long distributionSetId,
@PathVariable final String metadataKey, @RequestBody final MetadataRest metadata) {
@Override
public ResponseEntity<MetadataRest> updateMetadata(final Long distributionSetId, final String metadataKey,
final MetadataRest metadata) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
final DistributionSetMetadata updated = distributionSetManagement
final DistributionSetMetadata updated = this.distributionSetManagement
.updateDistributionSetMetadata(new DistributionSetMetadata(metadataKey, ds, metadata.getValue()));
return ResponseEntity.ok(DistributionSetMapper.toResponseDsMetadata(updated));
}
/**
* Deletes a single meta data entry from the distribution set.
*
* @param distributionSetId
* the ID of the distribution set to delete the meta data entry
* @param metadataKey
* the key of the meta data to delete
* @return status OK if the delete request is successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/metadata/{metadataKey}")
public ResponseEntity<Void> deleteMetadata(@PathVariable final Long distributionSetId,
@PathVariable final String metadataKey) {
@Override
public ResponseEntity<Void> deleteMetadata(final Long distributionSetId, final String metadataKey) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
distributionSetManagement.deleteDistributionSetMetadata(new DsMetadataCompositeKey(ds, metadataKey));
this.distributionSetManagement.deleteDistributionSetMetadata(new DsMetadataCompositeKey(ds, metadataKey));
return ResponseEntity.ok().build();
}
/**
* Creates a list of meta data for a specific distribution set.
*
* @param distributionSetId
* the ID of the distribution set to create meta data for
* @param metadataRest
* the list of meta data entries to create
* @return status created if post request is successful with the value of
* the created meta data
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/metadata", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<List<MetadataRest>> createMetadata(@PathVariable final Long distributionSetId,
@RequestBody final List<MetadataRest> metadataRest) {
@Override
public ResponseEntity<List<MetadataRest>> createMetadata(final Long distributionSetId,
final List<MetadataRest> metadataRest) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
final List<DistributionSetMetadata> created = distributionSetManagement
final List<DistributionSetMetadata> created = this.distributionSetManagement
.createDistributionSetMetadata(DistributionSetMapper.fromRequestDsMetadata(ds, metadataRest));
return new ResponseEntity<>(DistributionSetMapper.toResponseDsMetadata(created), HttpStatus.CREATED);
}
/**
* Assigns a list of software modules to a distribution set.
*
* @param distributionSetId
* the ID of the distribution set to assign software modules for
* @param softwareModuleIDs
* the list of software modules ids to assign
* @return {@link HttpStatus#OK}
*
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedSM", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> assignSoftwareModules(@PathVariable final Long distributionSetId,
@RequestBody final List<SoftwareModuleAssigmentRest> softwareModuleIDs) {
@Override
public ResponseEntity<Void> assignSoftwareModules(final Long distributionSetId,
final List<SoftwareModuleAssigmentRest> softwareModuleIDs) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
final Set<SoftwareModule> softwareModuleToBeAssigned = new HashSet<>();
for (final SoftwareModuleAssigmentRest sm : softwareModuleIDs) {
final SoftwareModule softwareModule = softwareManagement.findSoftwareModuleById(sm.getId());
final SoftwareModule softwareModule = this.softwareManagement.findSoftwareModuleById(sm.getId());
if (softwareModule != null) {
softwareModuleToBeAssigned.add(softwareModule);
} else {
@@ -538,63 +308,23 @@ public class DistributionSetResource {
}
}
// Add Softwaremodules to DisSet only if all of them were found
distributionSetManagement.assignSoftwareModules(ds, softwareModuleToBeAssigned);
this.distributionSetManagement.assignSoftwareModules(ds, softwareModuleToBeAssigned);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Deletes the assignment of the software module form the distribution set.
*
* @param distributionSetId
* the ID of the distribution set to reject the software module
* for
* @param softwareModuleId
* the software module id to get rejected form the distribution
* set
* @return status OK if rejection was successful.
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/assignedSM/{softwareModuleId}")
public ResponseEntity<Void> deleteAssignSoftwareModules(@PathVariable final Long distributionSetId,
@PathVariable final Long softwareModuleId) {
@Override
public ResponseEntity<Void> deleteAssignSoftwareModules(final Long distributionSetId, final Long softwareModuleId) {
// check if distribution set and software module exist otherwise throw
// exception immediately
final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId);
final SoftwareModule sm = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId);
distributionSetManagement.unassignSoftwareModule(ds, sm);
this.distributionSetManagement.unassignSoftwareModule(ds, sm);
return ResponseEntity.ok().build();
}
/**
* Handles the GET request for retrieving the assigned software modules of a
* specific distribution set.
*
* @param distributionSetId
* the ID of the distribution to retrieve
* @param pagingOffsetParam
* the offset of list of sets 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}
* @return a list of the assigned software modules of a distribution set
* with status OK, if none is assigned than {@code null}
* @throws EntityNotFoundException
* in case no distribution set with the given
* {@code distributionSetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedSM", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModulePagedList> getAssignedSoftwareModules(
@PathVariable final Long distributionSetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam) {
@Override
public ResponseEntity<SoftwareModulePagedList> getAssignedSoftwareModules(final Long distributionSetId,
final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) {
// check if distribution set exists otherwise throw exception
// immediately
final DistributionSet foundDs = findDistributionSetWithExceptionIfNotFound(distributionSetId);
@@ -602,7 +332,7 @@ public class DistributionSetResource {
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
final Sort sorting = PagingUtility.sanitizeSoftwareModuleSortParam(sortParam);
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<SoftwareModule> softwaremodules = softwareManagement.findSoftwareModuleByAssignedTo(pageable,
final Page<SoftwareModule> softwaremodules = this.softwareManagement.findSoftwareModuleByAssignedTo(pageable,
foundDs);
return new ResponseEntity<>(
new SoftwareModulePagedList(SoftwareModuleMapper.toResponse(softwaremodules.getContent()),
@@ -611,7 +341,7 @@ public class DistributionSetResource {
}
private DistributionSet findDistributionSetWithExceptionIfNotFound(final Long distributionSetId) {
final DistributionSet set = distributionSetManagement.findDistributionSetById(distributionSetId);
final DistributionSet set = this.distributionSetManagement.findDistributionSetById(distributionSetId);
if (set == null) {
throw new EntityNotFoundException("DistributionSet with Id {" + distributionSetId + "} does not exist");
}
@@ -620,7 +350,7 @@ public class DistributionSetResource {
}
private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId) {
final SoftwareModule sm = softwareManagement.findSoftwareModuleById(softwareModuleId);
final SoftwareModule sm = this.softwareManagement.findSoftwareModuleById(softwareModuleId);
if (sm == null) {
throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist");
}

View File

@@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssigmentResult;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi;
import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest;
@@ -34,13 +35,7 @@ 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.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;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -48,8 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
*
*/
@RestController
@RequestMapping(RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING)
public class DistributionSetTagResource {
public class DistributionSetTagResource implements DistributionSetTagRestApi {
private static final Logger LOG = LoggerFactory.getLogger(DistributionSetTagResource.class);
@Autowired
@@ -58,32 +52,9 @@ public class DistributionSetTagResource {
@Autowired
private DistributionSetManagement distributionSetManagement;
/**
* Handles the GET request of retrieving all DistributionSet tags.
*
* @param pagingOffsetParam
* the offset of list of DistributionSet tags 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 target tags 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 })
public ResponseEntity<TagPagedList> getDistributionSetTags(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TagPagedList> getDistributionSetTags(final int pagingOffsetParam, final int pagingLimitParam,
final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -93,11 +64,11 @@ public class DistributionSetTagResource {
final Slice<DistributionSetTag> findTargetsAll;
final Long countTargetsAll;
if (rsqlParam == null) {
findTargetsAll = tagManagement.findAllDistributionSetTags(pageable);
countTargetsAll = tagManagement.countTargetTags();
findTargetsAll = this.tagManagement.findAllDistributionSetTags(pageable);
countTargetsAll = this.tagManagement.countTargetTags();
} else {
final Page<DistributionSetTag> findTargetPage = tagManagement
final Page<DistributionSetTag> findTargetPage = this.tagManagement
.findAllDistributionSetTags(RSQLUtility.parse(rsqlParam, TagFields.class), pageable);
countTargetsAll = findTargetPage.getTotalElements();
findTargetsAll = findTargetPage;
@@ -108,141 +79,63 @@ public class DistributionSetTagResource {
return new ResponseEntity<>(new TagPagedList(rest, countTargetsAll), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
*
* @return a single distribution set tag with status OK.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionsetTagId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> getDistributionSetTag(@PathVariable final Long distributionsetTagId) {
@Override
public ResponseEntity<TagRest> getDistributionSetTag(final Long distributionsetTagId) {
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
return new ResponseEntity<>(TagMapper.toResponse(tag), HttpStatus.OK);
}
/**
* Handles the POST request of creating new distribution set tag. The
* request body must always be a list of tags.
*
* @param tags
* the distribution set tags to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created. The Response Body are the created
* distribution set tags but without ResponseBody.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagsRest> createDistributionSetTags(@RequestBody final List<TagRequestBodyPut> tags) {
@Override
public ResponseEntity<TagsRest> createDistributionSetTags(final List<TagRequestBodyPut> tags) {
LOG.debug("creating {} ds tags", tags.size());
final List<DistributionSetTag> createdTags = tagManagement
final List<DistributionSetTag> createdTags = this.tagManagement
.createDistributionSetTags(TagMapper.mapDistributionSetTagFromRequest(tags));
return new ResponseEntity<>(TagMapper.toResponseDistributionSetTag(createdTags), HttpStatus.CREATED);
}
/**
*
* Handles the PUT request of updating a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @param restDSTagRest
* the the request body to be updated
* @return status OK if update is successful and the updated distribution
* set tag.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionsetTagId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> updateDistributionSetTag(@PathVariable final Long distributionsetTagId,
@RequestBody final TagRequestBodyPut restDSTagRest) {
@Override
public ResponseEntity<TagRest> updateDistributionSetTag(final Long distributionsetTagId,
final TagRequestBodyPut restDSTagRest) {
LOG.debug("update {} ds tag", restDSTagRest);
final DistributionSetTag distributionSetTag = findDistributionTagById(distributionsetTagId);
TagMapper.updateTag(restDSTagRest, distributionSetTag);
final DistributionSetTag updateDistributionSetTag = tagManagement.updateDistributionSetTag(distributionSetTag);
final DistributionSetTag updateDistributionSetTag = this.tagManagement
.updateDistributionSetTag(distributionSetTag);
LOG.debug("ds tag updated");
return new ResponseEntity<>(TagMapper.toResponse(updateDistributionSetTag), HttpStatus.OK);
}
/**
* Handles the DELETE request for a single distribution set tag.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @return status OK if delete as successfully.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionsetTagId}")
public ResponseEntity<Void> deleteDistributionSetTag(@PathVariable final Long distributionsetTagId) {
@Override
public ResponseEntity<Void> deleteDistributionSetTag(final Long distributionsetTagId) {
LOG.debug("Delete {} distribution set tag", distributionsetTagId);
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
tagManagement.deleteDistributionSetTag(tag.getName());
this.tagManagement.deleteDistributionSetTag(tag.getName());
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the GET request of retrieving all assigned distribution sets by
* the given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag
*
* @return the list of assigned distribution sets.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.GET, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<DistributionSetsRest> getAssignedDistributionSets(
@PathVariable final Long distributionsetTagId) {
@Override
public ResponseEntity<DistributionSetsRest> getAssignedDistributionSets(final Long distributionsetTagId) {
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
return new ResponseEntity<>(
DistributionSetMapper.toResponseDistributionSets(tag.getAssignedToDistributionSet()), HttpStatus.OK);
}
/**
* Handles the POST request to toggle the assignment of distribution sets by
* the given tag id.
*
* @param distributionsetTagIds
* the ID of the distribution set tag to retrieve
* @param assignedDSRequestBodies
* list of distribution set ids to be toggled
*
* @return the list of assigned distribution sets and unassigned
* distribution sets.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING
+ "/toggleTagAssignment")
public ResponseEntity<DistributionSetTagAssigmentResultRest> toggleTagAssignment(
@PathVariable final Long distributionsetTagId,
@RequestBody final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies) {
@Override
public ResponseEntity<DistributionSetTagAssigmentResultRest> toggleTagAssignment(final Long distributionsetTagId,
final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies) {
LOG.debug("Toggle distribution set assignment {} for ds tag {}", assignedDSRequestBodies.size(),
distributionsetTagId);
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
final DistributionSetTagAssigmentResult assigmentResult = distributionSetManagement
final DistributionSetTagAssigmentResult assigmentResult = this.distributionSetManagement
.toggleTagAssignment(findDistributionSetIds(assignedDSRequestBodies), tag.getName());
final DistributionSetTagAssigmentResultRest tagAssigmentResultRest = new DistributionSetTagAssigmentResultRest();
@@ -257,44 +150,20 @@ public class DistributionSetTagResource {
return new ResponseEntity<>(tagAssigmentResultRest, HttpStatus.OK);
}
/**
* Handles the POST request to assign distribution sets to the given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
* @param assignedDSRequestBodies
* list of distribution sets ids to be assigned
*
* @return the list of assigned distribution set.
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<DistributionSetsRest> assignDistributionSets(@PathVariable final Long distributionsetTagId,
@RequestBody final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies) {
@Override
public ResponseEntity<DistributionSetsRest> assignDistributionSets(final Long distributionsetTagId,
final List<AssignedDistributionSetRequestBody> assignedDSRequestBodies) {
LOG.debug("Assign DistributionSet {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId);
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
final List<DistributionSet> assignedDs = distributionSetManagement
final List<DistributionSet> assignedDs = this.distributionSetManagement
.assignTag(findDistributionSetIds(assignedDSRequestBodies), tag);
LOG.debug("Assignd DistributionSet {}", assignedDs.size());
return new ResponseEntity<>(DistributionSetMapper.toResponseDistributionSets(assignedDs), HttpStatus.OK);
}
/**
* Handles the DELETE request to unassign all distribution set from the
* given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING)
public ResponseEntity<Void> unassignDistributionSets(@PathVariable final Long distributionsetTagId) {
@Override
public ResponseEntity<Void> unassignDistributionSets(final Long distributionsetTagId) {
LOG.debug("Unassign all DS for ds tag {}", distributionsetTagId);
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
if (tag.getAssignedToDistributionSet() == null) {
@@ -302,36 +171,22 @@ public class DistributionSetTagResource {
return new ResponseEntity<>(HttpStatus.OK);
}
final List<DistributionSet> distributionSets = distributionSetManagement.unAssignAllDistributionSetsByTag(tag);
final List<DistributionSet> distributionSets = this.distributionSetManagement
.unAssignAllDistributionSetsByTag(tag);
LOG.debug("Unassigned ds {}", distributionSets.size());
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the DELETE request to unassign one distribution set from the
* given tag id.
*
* @param distributionsetTagId
* the ID of the distribution set tag
* @param distributionsetId
* the ID of the distribution set to unassign
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code distributionsetTagId} doesn't
* exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING
+ "/{distributionsetId}")
public ResponseEntity<Void> unassignDistributionSet(@PathVariable final Long distributionsetTagId,
@PathVariable final Long distributionsetId) {
@Override
public ResponseEntity<Void> unassignDistributionSet(final Long distributionsetTagId, final Long distributionsetId) {
LOG.debug("Unassign ds {} for ds tag {}", distributionsetId, distributionsetTagId);
final DistributionSetTag tag = findDistributionTagById(distributionsetTagId);
distributionSetManagement.unAssignTag(distributionsetId, tag);
this.distributionSetManagement.unAssignTag(distributionsetId, tag);
return new ResponseEntity<>(HttpStatus.OK);
}
private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) {
final DistributionSetTag tag = tagManagement.findDistributionSetTagById(distributionsetTagId);
final DistributionSetTag tag = this.tagManagement.findDistributionSetTagById(distributionsetTagId);
if (tag == null) {
throw new EntityNotFoundException("Distribution Tag with Id {" + distributionsetTagId + "} does not exist");
}

View File

@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRest;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypesRest;
@@ -101,13 +102,13 @@ final class DistributionSetTypeMapper {
result.setKey(type.getKey());
result.setModuleId(type.getId());
result.add(linkTo(methodOn(DistributionSetTypeResource.class).getDistributionSetType(result.getModuleId()))
result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getDistributionSetType(result.getModuleId()))
.withRel("self"));
result.add(linkTo(methodOn(DistributionSetTypeResource.class).getMandatoryModules(result.getModuleId()))
result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getMandatoryModules(result.getModuleId()))
.withRel(RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULES));
result.add(linkTo(methodOn(DistributionSetTypeResource.class).getOptionalModules(result.getModuleId()))
result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getOptionalModules(result.getModuleId()))
.withRel(RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES));
return result;

View File

@@ -19,6 +19,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.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.IdRest;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypePagedList;
import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost;
@@ -33,12 +34,9 @@ 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.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;
import org.springframework.web.bind.annotation.RestController;
@@ -47,12 +45,9 @@ import org.springframework.web.bind.annotation.RestController;
* {@link Artifact} CRUD operations.
*
*
*
*
*/
@RestController
@RequestMapping(RestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING)
public class DistributionSetTypeResource {
public class DistributionSetTypeResource implements DistributionSetTypeRestApi {
@Autowired
private SoftwareManagement softwareManagement;
@@ -60,30 +55,7 @@ public class DistributionSetTypeResource {
@Autowired
private DistributionSetManagement distributionSetManagement;
/**
* Handles the GET request of retrieving all {@link DistributionSetType}s
* within SP.
*
* @param pagingOffsetParam
* the offset of list of modules 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 {@link DistributionSetType} 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 })
@Override
public ResponseEntity<DistributionSetTypePagedList> getDistributionSetTypes(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@@ -112,19 +84,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(new DistributionSetTypePagedList(rest, countModulesAll), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single
* {@link DistributionSetType} within SP.
*
* @param distributionSetTypeId
* the ID of the module type to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<DistributionSetTypeRest> getDistributionSetType(
@PathVariable final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
@@ -132,15 +92,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(DistributionSetTypeMapper.toResponse(foundType), HttpStatus.OK);
}
/**
* Handles the DELETE request for a single Distribution Set Type within SP.
*
* @param distributionSetTypeId
* the ID of the module to retrieve
* @return status OK if delete as sucessfull.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}")
@Override
public ResponseEntity<Void> deleteDistributionSetType(@PathVariable final Long distributionSetTypeId) {
final DistributionSetType module = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
@@ -149,17 +101,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the PUT request of updating a Distribution Set Type within SP.
*
* @param distributionSetTypeId
* the ID of the software module in the URL
* @param restDistributionSetType
* the module type to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetTypeId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<DistributionSetTypeRest> updateDistributionSetType(
@PathVariable final Long distributionSetTypeId,
@RequestBody final DistributionSetTypeRequestBodyPut restDistributionSetType) {
@@ -176,19 +118,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(DistributionSetTypeMapper.toResponse(updatedDistributionSetType), HttpStatus.OK);
}
/**
* Handles the POST request of creating new {@link DistributionSetType}s
* within SP. The request body must always be a list of types.
*
* @param distributionSetTypes
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
@Override
public ResponseEntity<DistributionSetTypesRest> createDistributionSetTypes(
@RequestBody final List<DistributionSetTypeRequestBodyPost> distributionSetTypes) {
@@ -208,17 +138,7 @@ public class DistributionSetTypeResource {
return module;
}
/**
* Handles the GET request of retrieving the list of mandatory software
* module types in that distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleTypesRest> getMandatoryModules(@PathVariable final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
@@ -229,19 +149,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(rest, HttpStatus.OK);
}
/**
* Handles the GET request of retrieving the single mandatory software
* module type in that distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param softwareModuleTypeId
* of {@link SoftwareModuleType}.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleTypeRest> getMandatoryModule(@PathVariable final Long distributionSetTypeId,
@PathVariable final Long softwareModuleTypeId) {
@@ -257,19 +165,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving the single optional software module
* type in that distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param softwareModuleTypeId
* of {@link SoftwareModuleType}.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleTypeRest> getOptionalModule(@PathVariable final Long distributionSetTypeId,
@PathVariable final Long softwareModuleTypeId) {
@@ -285,17 +181,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving the list of optional software
* module types in that distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @return Unpaged list of module types and OK in case of success.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleTypesRest> getOptionalModules(@PathVariable final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
@@ -306,20 +192,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(rest, HttpStatus.OK);
}
/**
* Handles DELETE request for removing a mandatory module from the
* {@link DistributionSetType}.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param softwareModuleTypeId
* of the {@link SoftwareModuleType} to remove
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<Void> removeMandatoryModule(@PathVariable final Long distributionSetTypeId,
@PathVariable final Long softwareModuleTypeId) {
@@ -339,20 +212,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles DELETE request for removing an optional module from the
* {@link DistributionSetType}.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param softwareModuleTypeId
* of the {@link SoftwareModuleType} to remove
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES
+ "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<Void> removeOptionalModule(@PathVariable final Long distributionSetTypeId,
@PathVariable final Long softwareModuleTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
@@ -371,21 +231,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the POST request for adding a mandatory software module type to a
* distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param smtId
* of the {@link SoftwareModuleType} to add
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<Void> addMandatoryModule(@PathVariable final Long distributionSetTypeId,
@RequestBody final IdRest smtId) {
@@ -400,21 +246,7 @@ public class DistributionSetTypeResource {
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the POST request for adding an optional software module type to a
* distribution set type.
*
* @param distributionSetTypeId
* of the {@link DistributionSetType}.
* @param smtId
* of the {@link SoftwareModuleType} to add
*
* @return OK if the request was successful
*/
@RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/"
+ RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<Void> addOptionalModule(@PathVariable final Long distributionSetTypeId,
@RequestBody final IdRest smtId) {

View File

@@ -0,0 +1,92 @@
/**
* 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.rest.resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Jonathan Knoblauch
*
*/
@RestController
@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
public class DownloadArtifactResource {
@Autowired
private SoftwareManagement softwareManagement;
@Autowired
private ArtifactManagement artifactManagement;
/**
* Handles the GET request for downloading an artifact.
*
* @param softwareModuleId
* of the parent SoftwareModule
* @param artifactId
* of the related LocalArtifact
* @param servletResponse
* of the servlet
* @param request
* of the client
*
* @return responseEntity with status ok if successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}/download")
@ResponseBody
public ResponseEntity<Void> downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId, final HttpServletResponse servletResponse,
final HttpServletRequest request) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
if (null == module || !module.getLocalArtifact(artifactId).isPresent()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
final LocalArtifact artifact = module.getLocalArtifact(artifactId).get();
final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact);
final String ifMatch = request.getHeader("If-Match");
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
}
return RestResourceConversionHelper.writeFileResponse(artifact, servletResponse, request, file);
}
private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId,
final Long artifactId) {
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
if (module == null) {
throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist");
} else if (artifactId != null && !module.getLocalArtifact(artifactId).isPresent()) {
throw new EntityNotFoundException("Artifact with Id {" + artifactId + "} does not exist");
}
return module;
}
}

View File

@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondit
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessAction;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition.Condition;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutErrorAction.ErrorAction;
@@ -70,12 +71,12 @@ final class RolloutMapper {
rollout.getTotalTargetCountStatus().getTotalTargetCountByStatus(status));
}
body.add(linkTo(methodOn(RolloutResource.class).getRollout(rollout.getId())).withRel("self"));
body.add(linkTo(methodOn(RolloutResource.class).start(rollout.getId(), false)).withRel("start"));
body.add(linkTo(methodOn(RolloutResource.class).start(rollout.getId(), true)).withRel("startAsync"));
body.add(linkTo(methodOn(RolloutResource.class).pause(rollout.getId())).withRel("pause"));
body.add(linkTo(methodOn(RolloutResource.class).resume(rollout.getId())).withRel("resume"));
body.add(linkTo(methodOn(RolloutResource.class).getRolloutGroups(rollout.getId(),
body.add(linkTo(methodOn(RolloutRestApi.class).getRollout(rollout.getId())).withRel("self"));
body.add(linkTo(methodOn(RolloutRestApi.class).start(rollout.getId(), false)).withRel("start"));
body.add(linkTo(methodOn(RolloutRestApi.class).start(rollout.getId(), true)).withRel("startAsync"));
body.add(linkTo(methodOn(RolloutRestApi.class).pause(rollout.getId())).withRel("pause"));
body.add(linkTo(methodOn(RolloutRestApi.class).resume(rollout.getId())).withRel("resume"));
body.add(linkTo(methodOn(RolloutRestApi.class).getRolloutGroups(rollout.getId(),
Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET),
Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, null)).withRel("groups"));
return body;
@@ -115,8 +116,9 @@ final class RolloutMapper {
body.setName(rolloutGroup.getName());
body.setRolloutGroupId(rolloutGroup.getId());
body.setStatus(rolloutGroup.getStatus().toString().toLowerCase());
body.add(linkTo(methodOn(RolloutResource.class).getRolloutGroup(rolloutGroup.getRollout().getId(),
rolloutGroup.getId())).withRel("self"));
body.add(linkTo(
methodOn(RolloutRestApi.class).getRolloutGroup(rolloutGroup.getRollout().getId(), rolloutGroup.getId()))
.withRel("self"));
return body;
}

View File

@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessActi
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutPagedList;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody;
import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody;
@@ -40,13 +41,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
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;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -54,8 +50,9 @@ import org.springframework.web.bind.annotation.RestController;
*
*/
@RestController
@RequestMapping(RestConstants.ROLLOUT_V1_REQUEST_MAPPING)
public class RolloutResource {
public class RolloutResource implements RolloutRestApi {
private static final String DOES_NOT_EXIST = "} does not exist";
@Autowired
private RolloutManagement rolloutManagement;
@@ -66,31 +63,9 @@ public class RolloutResource {
@Autowired
private DistributionSetManagement distributionSetManagement;
/**
* Handles the GET request of retrieving all rollouts.
*
* @param pagingOffsetParam
* the offset of list of rollouts 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 rollouts 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 = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutPagedList> getRollouts(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<RolloutPagedList> getRollouts(final int pagingOffsetParam, final int pagingLimitParam,
final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -100,50 +75,28 @@ public class RolloutResource {
final Page<Rollout> findModulesAll;
if (rsqlParam != null) {
findModulesAll = rolloutManagement
findModulesAll = this.rolloutManagement
.findAllWithDetailedStatusByPredicate(RSQLUtility.parse(rsqlParam, RolloutFields.class), pageable);
} else {
findModulesAll = rolloutManagement.findAll(pageable);
findModulesAll = this.rolloutManagement.findAll(pageable);
}
final List<RolloutResponseBody> rest = RolloutMapper.toResponseRollout(findModulesAll.getContent());
return new ResponseEntity<>(new RolloutPagedList(rest, findModulesAll.getTotalElements()), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single rollout.
*
* @param rolloutId
* the ID of the rollout to retrieve
* @return a single rollout with status OK.
* @throws EntityNotFoundException
* in case no rollout with the given {@code rolloutId} exists.
*/
@RequestMapping(value = "/{rolloutId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" })
public ResponseEntity<RolloutResponseBody> getRollout(@PathVariable("rolloutId") final Long rolloutId) {
@Override
public ResponseEntity<RolloutResponseBody> getRollout(final Long rolloutId) {
final Rollout findRolloutById = findRolloutOrThrowException(rolloutId);
return new ResponseEntity<>(RolloutMapper.toResponseRollout(findRolloutById), HttpStatus.OK);
}
/**
* Handles the POST request for creating rollout.
*
* @param rollout
* the rollout body to be created.
* @return In case rollout could successful created the ResponseEntity with
* status code 201 with the successfully created rollout. In any
* failure the JsonResponseExceptionHandler is handling the
* response.
* @throws EntityNotFoundException
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<RolloutResponseBody> create(@RequestBody final RolloutRestRequestBody rolloutRequestBody) {
// first check the given RSQL query if it's well formed, otherwise and
// exception is thrown
RSQLUtility.isValid(rolloutRequestBody.getTargetFilterQuery());
RSQLUtility.parse(rolloutRequestBody.getTargetFilterQuery(), TargetFields.class);
final DistributionSet distributionSet = findDistributionSetOrThrowException(rolloutRequestBody);
@@ -181,7 +134,7 @@ public class RolloutResource {
.successCondition(successCondition, successConditionExpr)
.successAction(successAction, successActionExpr).errorCondition(errorCondition, errorConditionExpr)
.errorAction(errorAction, errorActionExpr).build();
final Rollout rollout = rolloutManagement.createRollout(
final Rollout rollout = this.rolloutManagement.createRollout(
RolloutMapper.fromRequest(rolloutRequestBody, distributionSet,
rolloutRequestBody.getTargetFilterQuery()),
rolloutRequestBody.getAmountGroups(), rolloutGroupConditions);
@@ -189,97 +142,34 @@ public class RolloutResource {
return ResponseEntity.status(HttpStatus.CREATED).body(RolloutMapper.toResponseRollout(rollout));
}
/**
* Handles the POST request for starting a rollout.
*
* @param rolloutId
* the ID of the rollout to be started.
* @return OK response (200) if rollout could be started. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#startRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/start", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> start(@PathVariable("rolloutId") final Long rolloutId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_ASYNC, defaultValue = "false") final boolean startAsync) {
@Override
public ResponseEntity<Void> start(final Long rolloutId, final boolean startAsync) {
final Rollout rollout = findRolloutOrThrowException(rolloutId);
if (startAsync) {
rolloutManagement.startRolloutAsync(rollout);
this.rolloutManagement.startRolloutAsync(rollout);
} else {
rolloutManagement.startRollout(rollout);
this.rolloutManagement.startRollout(rollout);
}
return ResponseEntity.ok().build();
}
/**
* Handles the POST request for pausing a rollout.
*
* @param rolloutId
* the ID of the rollout to be paused.
* @return OK response (200) if rollout could be paused. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#pauseRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/pause", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> pause(@PathVariable("rolloutId") final Long rolloutId) {
@Override
public ResponseEntity<Void> pause(final Long rolloutId) {
final Rollout rollout = findRolloutOrThrowException(rolloutId);
rolloutManagement.pauseRollout(rollout);
this.rolloutManagement.pauseRollout(rollout);
return ResponseEntity.ok().build();
}
/**
* Handles the POST request for resuming a rollout.
*
* @param rolloutId
* the ID of the rollout to be resumed.
* @return OK response (200) if rollout could be resumed. In case of any
* exception the corresponding errors occur.
* @throws EntityNotFoundException
* @see RolloutManagement#resumeRollout(Rollout)
* @see ResponseExceptionHandler
*/
@RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/resume", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> resume(@PathVariable("rolloutId") final Long rolloutId) {
@Override
public ResponseEntity<Void> resume(final Long rolloutId) {
final Rollout rollout = findRolloutOrThrowException(rolloutId);
rolloutManagement.resumeRollout(rollout);
this.rolloutManagement.resumeRollout(rollout);
return ResponseEntity.ok().build();
}
/**
* Handles the GET request of retrieving all rollout groups referred to a
* rollout.
*
* @param pagingOffsetParam
* the offset of list of rollout groups 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 rollout groups referred to a rollout 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, value = "/{rolloutId}/deploygroups", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutGroupPagedList> getRolloutGroups(@PathVariable("rolloutId") final Long rolloutId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<RolloutGroupPagedList> getRolloutGroups(final Long rolloutId, final int pagingOffsetParam,
final int pagingLimitParam, final String sortParam, final String rsqlParam) {
final Rollout rollout = findRolloutOrThrowException(rolloutId);
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
@@ -290,10 +180,10 @@ public class RolloutResource {
final Page<RolloutGroup> findRolloutGroupsAll;
if (rsqlParam != null) {
findRolloutGroupsAll = rolloutGroupManagement.findRolloutGroupsByPredicate(rollout,
findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByPredicate(rollout,
RSQLUtility.parse(rsqlParam, RolloutGroupFields.class), pageable);
} else {
findRolloutGroupsAll = rolloutGroupManagement.findRolloutGroupsByRolloutId(rolloutId, pageable);
findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByRolloutId(rolloutId, pageable);
}
final List<RolloutGroupResponseBody> rest = RolloutMapper
@@ -302,56 +192,16 @@ public class RolloutResource {
HttpStatus.OK);
}
/**
* Handles the GET request for retrieving a single rollout group.
*
* @param rolloutId
* the rolloutId to retrieve the group from
* @param groupId
* the groupId to retrieve the rollout group
* @return the OK response containing the {@link RolloutGroupResponseBody}
* @throws EntityNotFoundException
*/
@RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<RolloutGroupResponseBody> getRolloutGroup(@PathVariable("rolloutId") final Long rolloutId,
@PathVariable("groupId") final Long groupId) {
@Override
public ResponseEntity<RolloutGroupResponseBody> getRolloutGroup(final Long rolloutId, final Long groupId) {
findRolloutOrThrowException(rolloutId);
final RolloutGroup rolloutGroup = findRolloutGroupOrThrowException(groupId);
return ResponseEntity.ok(RolloutMapper.toResponseRolloutGroup(rolloutGroup));
}
/**
* Retrieves all targets related to a specific rollout group.
*
* @param rolloutId
* the ID of the rollout
* @param groupId
* the ID of the rollout group
* @param pagingOffsetParam
* the offset of list of rollout groups 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 paged list of targets related to a specific rollout and rollout
* group.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}/targets", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
public ResponseEntity<TargetPagedList> getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId,
@PathVariable("groupId") final Long groupId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TargetPagedList> getRolloutGroupTargets(final Long rolloutId, final Long groupId,
final int pagingOffsetParam, final int pagingLimitParam, final String sortParam, final String rsqlParam) {
findRolloutOrThrowException(rolloutId);
final RolloutGroup rolloutGroup = findRolloutGroupOrThrowException(groupId);
@@ -364,10 +214,11 @@ public class RolloutResource {
final Page<Target> rolloutGroupTargets;
if (rsqlParam != null) {
final Specification<Target> rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class);
rolloutGroupTargets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, rsqlSpecification,
rolloutGroupTargets = this.rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, rsqlSpecification,
pageable);
} else {
final Page<Target> pageTargets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, pageable);
final Page<Target> pageTargets = this.rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup,
pageable);
rolloutGroupTargets = pageTargets;
}
final List<TargetRest> rest = TargetMapper.toResponse(rolloutGroupTargets.getContent());
@@ -375,27 +226,27 @@ public class RolloutResource {
}
private Rollout findRolloutOrThrowException(final Long rolloutId) {
final Rollout rollout = rolloutManagement.findRolloutWithDetailedStatus(rolloutId);
final Rollout rollout = this.rolloutManagement.findRolloutWithDetailedStatus(rolloutId);
if (rollout == null) {
throw new EntityNotFoundException("Rollout with Id {" + rolloutId + "} does not exist");
throw new EntityNotFoundException("Rollout with Id {" + rolloutId + DOES_NOT_EXIST);
}
return rollout;
}
private RolloutGroup findRolloutGroupOrThrowException(final Long rolloutGroupId) {
final RolloutGroup rolloutGroup = rolloutGroupManagement.findRolloutGroupById(rolloutGroupId);
final RolloutGroup rolloutGroup = this.rolloutGroupManagement.findRolloutGroupById(rolloutGroupId);
if (rolloutGroup == null) {
throw new EntityNotFoundException("Group with Id {" + rolloutGroupId + "} does not exist");
throw new EntityNotFoundException("Group with Id {" + rolloutGroupId + DOES_NOT_EXIST);
}
return rolloutGroup;
}
private DistributionSet findDistributionSetOrThrowException(final RolloutRestRequestBody rolloutRequestBody) {
final DistributionSet ds = distributionSetManagement
final DistributionSet ds = this.distributionSetManagement
.findDistributionSetById(rolloutRequestBody.getDistributionSetId());
if (ds == null) {
throw new EntityNotFoundException(
"DistributionSet with Id {" + rolloutRequestBody.getDistributionSetId() + "} does not exist");
"DistributionSet with Id {" + rolloutRequestBody.getDistributionSetId() + DOES_NOT_EXIST);
}
return ds;
}

View File

@@ -21,6 +21,8 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest;
@@ -142,13 +144,13 @@ public final class SoftwareModuleMapper {
response.setType(baseSofwareModule.getType().getKey());
response.setVendor(baseSofwareModule.getVendor());
response.add(linkTo(methodOn(SoftwareModuleResource.class).getArtifacts(response.getModuleId()))
response.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getArtifacts(response.getModuleId()))
.withRel(RestConstants.SOFTWAREMODULE_V1_ARTIFACT));
response.add(linkTo(methodOn(SoftwareModuleResource.class).getSoftwareModule(response.getModuleId()))
response.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getSoftwareModule(response.getModuleId()))
.withRel("self"));
response.add(linkTo(
methodOn(SoftwareModuleTypeResource.class).getSoftwareModuleType(baseSofwareModule.getType().getId()))
methodOn(SoftwareModuleTypeRestApi.class).getSoftwareModuleType(baseSofwareModule.getType().getId()))
.withRel(RestConstants.SOFTWAREMODULE_V1_TYPE));
response.add(linkTo(methodOn(SoftwareModuleResource.class).getMetadata(response.getModuleId(),
@@ -178,13 +180,13 @@ public final class SoftwareModuleMapper {
RestModelMapper.mapBaseToBase(artifactRest, artifact);
artifactRest.add(linkTo(methodOn(SoftwareModuleResource.class).getArtifact(artifact.getSoftwareModule().getId(),
artifactRest.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getArtifact(artifact.getSoftwareModule().getId(),
artifact.getId())).withRel("self"));
if (artifact instanceof LocalArtifact) {
artifactRest.add(
linkTo(methodOn(SoftwareModuleResource.class).downloadArtifact(artifact.getSoftwareModule().getId(),
artifact.getId(), null, null)).withRel("download"));
artifactRest.add(linkTo(methodOn(DownloadArtifactResource.class)
.downloadArtifact(artifact.getSoftwareModule().getId(), artifact.getId(), null, null))
.withRel("download"));
}
return artifactRest;

View File

@@ -11,22 +11,17 @@ package org.eclipse.hawkbit.rest.resource;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI;
import org.eclipse.hawkbit.rest.resource.model.MetadataRest;
import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest;
@@ -44,14 +39,10 @@ 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.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;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@@ -59,13 +50,9 @@ import org.springframework.web.multipart.MultipartFile;
* REST Resource handling for {@link SoftwareModule} and related
* {@link Artifact} CRUD operations.
*
*
*
*
*/
@RestController
@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
public class SoftwareModuleResource {
public class SoftwareModuleResource implements SoftwareModuleRestAPI {
private static final Logger LOG = LoggerFactory.getLogger(SoftwareModuleResource.class);
@Autowired
@@ -74,25 +61,7 @@ public class SoftwareModuleResource {
@Autowired
private SoftwareManagement softwareManagement;
/**
* Handles POST request for artifact upload.
*
* @param softwareModuleId
* of the parent {@link SoftwareModule}
* @param file
* that has to be uploaded
* @param optionalFileName
* to override {@link MultipartFile#getOriginalFilename()}
* @param md5Sum
* checksum for uploaded content check
* @param sha1Sum
* checksum for uploaded content check
*
* @return {@link ResponseEntity} if status {@link HttpStatus#CREATED} if
* successful
*/
@RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/artifacts", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<ArtifactRest> uploadArtifact(@PathVariable final Long softwareModuleId,
@RequestParam("file") final MultipartFile file,
@RequestParam(value = "filename", required = false) final String optionalFileName,
@@ -123,19 +92,7 @@ public class SoftwareModuleResource {
}
/**
* Handles the GET request of retrieving all meta data of artifacts assigned
* to a software module.
*
* @param softwareModuleId
* of the parent {@link SoftwareModule}
*
* @return {@link ResponseEntity} with status {@link HttpStatus#OK} if
* successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
@Override
public ResponseEntity<ArtifactsRest> getArtifacts(@PathVariable final Long softwareModuleId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
@@ -146,55 +103,49 @@ public class SoftwareModuleResource {
* Handles the GET request for downloading an artifact.
*
* @param softwareModuleId
* of the parent {@link SoftwareModule}
* of the parent SoftwareModule
* @param artifactId
* of the related {@link LocalArtifact}
* of the related LocalArtifact
* @param servletResponse
* of the servlet
* @param request
* of the client
*
* @return {@link ResponseEntity} with status {@link HttpStatus#OK} if
* successful
* @return responseEntity with status ok if successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}/download")
@ResponseBody
public ResponseEntity<Void> downloadArtifact(@PathVariable final Long softwareModuleId,
@PathVariable final Long artifactId, final HttpServletResponse servletResponse,
final HttpServletRequest request) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
// @RequestMapping(method = RequestMethod.GET, value =
// RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING
// + "/{softwareModuleId}/artifacts/{artifactId}/download")
// @ResponseBody
// public ResponseEntity<Void> downloadArtifact(@PathVariable final Long
// softwareModuleId,
// @PathVariable final Long artifactId, final HttpServletResponse
// servletResponse,
// final HttpServletRequest request) {
// final SoftwareModule module =
// findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
//
// if (null == module || !module.getLocalArtifact(artifactId).isPresent()) {
// return new ResponseEntity<>(HttpStatus.NOT_FOUND);
// }
//
// final LocalArtifact artifact = module.getLocalArtifact(artifactId).get();
// final DbArtifact file =
// artifactManagement.loadLocalArtifactBinary(artifact);
//
// final String ifMatch = request.getHeader("If-Match");
// if (ifMatch != null &&
// !RestResourceConversionHelper.matchesHttpHeader(ifMatch,
// artifact.getSha1Hash())) {
// return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
// }
//
// return RestResourceConversionHelper.writeFileResponse(artifact,
// servletResponse, request, file);
//
// }
if (null == module || !module.getLocalArtifact(artifactId).isPresent()) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
final LocalArtifact artifact = module.getLocalArtifact(artifactId).get();
final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact);
final String ifMatch = request.getHeader("If-Match");
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
}
return RestResourceConversionHelper.writeFileResponse(artifact, servletResponse, request, file);
}
/**
* Handles the GET request of retrieving a single Artifact meta data
* request.
*
* @param softwareModuleId
* of the parent {@link SoftwareModule}
* @param artifactId
* of the related {@link LocalArtifact}
*
* @return {@link ResponseEntity} with status {@link HttpStatus#OK} if
* successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
@Override
public ResponseEntity<ArtifactRest> getArtifact(@PathVariable final Long softwareModuleId,
@PathVariable final Long artifactId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
@@ -203,18 +154,7 @@ public class SoftwareModuleResource {
HttpStatus.OK);
}
/**
* Handles the DELETE request for a single SoftwareModule within SP.
*
* @param softwareModuleId
* the ID of the module that has the artifact
* @param artifactId
* of the artifact to be deleted
*
* @return status OK if delete as successful.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/artifacts/{artifactId}")
@ResponseBody
@Override
public ResponseEntity<Void> deleteArtifact(@PathVariable final Long softwareModuleId,
@PathVariable final Long artifactId) {
findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
@@ -225,27 +165,7 @@ public class SoftwareModuleResource {
}
/**
* Handles the GET request of retrieving all softwaremodules within SP.
*
* @param pagingOffsetParam
* the offset of list of modules 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 modules 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 })
@Override
public ResponseEntity<SoftwareModulePagedList> getSoftwareModules(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@@ -273,38 +193,14 @@ public class SoftwareModuleResource {
return new ResponseEntity<>(new SoftwareModulePagedList(rest, countModulesAll), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single software module within SP.
*
* @param softwareModuleId
* the ID of the module to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleRest> getSoftwareModule(@PathVariable final Long softwareModuleId) {
final SoftwareModule findBaseSoftareModule = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
return new ResponseEntity<>(SoftwareModuleMapper.toResponse(findBaseSoftareModule), HttpStatus.OK);
}
/**
* Handles the POST request of creating new softwaremodules within SP. The
* request body must always be a list of modules. The requests is delgating
* to the {@link SoftwareManagement#createSoftwareModule(Iterable)}.
*
* @param softwareModules
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
@Override
public ResponseEntity<SoftwareModulesRest> createSoftwareModules(
@RequestBody final List<SoftwareModuleRequestBodyPost> softwareModules) {
LOG.debug("creating {} softwareModules", softwareModules.size());
@@ -316,18 +212,7 @@ public class SoftwareModuleResource {
HttpStatus.CREATED);
}
/**
* Handles the PUT request of updating a software module within SP.
* {@link SoftwareManagement#createSoftwareModule(Iterable)}.
*
* @param softwareModuleId
* the ID of the software module in the URL
* @param restSoftwareModule
* the modules to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<SoftwareModuleRest> updateSoftwareModule(@PathVariable final Long softwareModuleId,
@RequestBody final SoftwareModuleRequestBodyPut restSoftwareModule) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
@@ -344,15 +229,7 @@ public class SoftwareModuleResource {
return new ResponseEntity<>(SoftwareModuleMapper.toResponse(updateSoftwareModule), HttpStatus.OK);
}
/**
* Handles the DELETE request for a single softwaremodule within SP.
*
* @param softwareModuleId
* the ID of the module to retrieve
* @return status OK if delete as sucessfull.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}")
@Override
public ResponseEntity<Void> deleteSoftwareModule(@PathVariable final Long softwareModuleId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
@@ -361,28 +238,7 @@ public class SoftwareModuleResource {
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Gets a paged list of meta data for a software module.
*
* @param softwareModuleId
* the ID of the software module for the meta data
* @param pagingOffsetParam
* the offset of list of meta data 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=key==abc}
* @return status OK if get request is successful with the paged list of
* meta data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
@Override
public ResponseEntity<MetadataRestPageList> getMetadata(@PathVariable final Long softwareModuleId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@@ -412,18 +268,7 @@ public class SoftwareModuleResource {
HttpStatus.OK);
}
/**
* Gets a single meta data value for a specific key of a software module.
*
* @param softwareModuleId
* the ID of the software module to get the meta data from
* @param metadataKey
* the key of the meta data entry to retrieve the value from
* @return status OK if get request is successful with the value of the meta
* data
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<MetadataRest> getMetadataValue(@PathVariable final Long softwareModuleId,
@PathVariable final String metadataKey) {
// check if distribution set exists otherwise throw exception
@@ -433,18 +278,7 @@ public class SoftwareModuleResource {
return ResponseEntity.<MetadataRest> ok(SoftwareModuleMapper.toResponseSwMetadata(findOne));
}
/**
* Updates a single meta data value of a software module.
*
* @param softwareModuleId
* the ID of the software module to update the meta data entry
* @param metadataKey
* the key of the meta data to update the value
* @return status OK if the update request is successful and the updated
* meta data result
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = {
MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
@Override
public ResponseEntity<MetadataRest> updateMetadata(@PathVariable final Long softwareModuleId,
@PathVariable final String metadataKey, @RequestBody final MetadataRest metadata) {
// check if software module exists otherwise throw exception immediately
@@ -454,16 +288,7 @@ public class SoftwareModuleResource {
return ResponseEntity.ok(SoftwareModuleMapper.toResponseSwMetadata(updated));
}
/**
* Deletes a single meta data entry from the software module.
*
* @param softwareModuleId
* the ID of the software module to delete the meta data entry
* @param metadataKey
* the key of the meta data to delete
* @return status OK if the delete request is successful
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/metadata/{metadataKey}")
@Override
public ResponseEntity<Void> deleteMetadata(@PathVariable final Long softwareModuleId,
@PathVariable final String metadataKey) {
// check if software module exists otherwise throw exception immediately
@@ -472,19 +297,7 @@ public class SoftwareModuleResource {
return ResponseEntity.ok().build();
}
/**
* Creates a list of meta data for a specific software module.
*
* @param softwareModuleId
* the ID of the distribution set to create meta data for
* @param metadataRest
* the list of meta data entries to create
* @return status created if post request is successful with the value of
* the created meta data
*/
@RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/metadata", consumes = {
MediaType.APPLICATION_JSON_VALUE,
"application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" })
@Override
public ResponseEntity<List<MetadataRest>> createMetadata(@PathVariable final Long softwareModuleId,
@RequestBody final List<MetadataRest> metadataRest) {
// check if software module exists otherwise throw exception immediately

View File

@@ -16,6 +16,7 @@ import java.util.Collection;
import java.util.List;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest;
@@ -73,7 +74,7 @@ final class SoftwareModuleTypeMapper {
result.setMaxAssignments(type.getMaxAssignments());
result.setModuleId(type.getId());
result.add(linkTo(methodOn(SoftwareModuleTypeResource.class).getSoftwareModuleType(result.getModuleId()))
result.add(linkTo(methodOn(SoftwareModuleTypeRestApi.class).getSoftwareModuleType(result.getModuleId()))
.withRel("self"));
return result;

View File

@@ -10,8 +10,6 @@ package org.eclipse.hawkbit.rest.resource;
import java.util.List;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -19,6 +17,7 @@ import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypePagedList;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost;
import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPut;
@@ -30,59 +29,22 @@ 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.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;
import org.springframework.web.bind.annotation.RestController;
/**
* REST Resource handling for {@link SoftwareModule} and related
* {@link Artifact} CRUD operations.
*
*
*
*
*/
@RestController
@RequestMapping(RestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING)
public class SoftwareModuleTypeResource {
public class SoftwareModuleTypeResource implements SoftwareModuleTypeRestApi {
@Autowired
private SoftwareManagement softwareManagement;
@Autowired
private EntityManager entityManager;
/**
* Handles the GET request of retrieving all {@link SoftwareModuleType}s
* within SP.
*
* @param pagingOffsetParam
* the offset of list of modules 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 module type 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 })
public ResponseEntity<SoftwareModuleTypePagedList> getTypes(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<SoftwareModuleTypePagedList> getTypes(final int pagingOffsetParam, final int pagingLimitParam,
final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -93,12 +55,12 @@ public class SoftwareModuleTypeResource {
final Slice<SoftwareModuleType> findModuleTypessAll;
Long countModulesAll;
if (rsqlParam != null) {
findModuleTypessAll = softwareManagement.findSoftwareModuleTypesByPredicate(
findModuleTypessAll = this.softwareManagement.findSoftwareModuleTypesByPredicate(
RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class), pageable);
countModulesAll = ((Page<SoftwareModuleType>) findModuleTypessAll).getTotalElements();
} else {
findModuleTypessAll = softwareManagement.findSoftwareModuleTypesAll(pageable);
countModulesAll = softwareManagement.countSoftwareModuleTypesAll();
findModuleTypessAll = this.softwareManagement.findSoftwareModuleTypesAll(pageable);
countModulesAll = this.softwareManagement.countSoftwareModuleTypesAll();
}
final List<SoftwareModuleTypeRest> rest = SoftwareModuleTypeMapper
@@ -106,56 +68,25 @@ public class SoftwareModuleTypeResource {
return new ResponseEntity<>(new SoftwareModuleTypePagedList(rest, countModulesAll), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single software module type
* within SP.
*
* @param softwareModuleTypeId
* the ID of the module type to retrieve
*
* @return a single softwareModule with status OK.
* @throws EntityNotFoundException
* in case no with the given {@code softwareModuleId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleTypeId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> getSoftwareModuleType(@PathVariable final Long softwareModuleTypeId) {
@Override
public ResponseEntity<SoftwareModuleTypeRest> getSoftwareModuleType(final Long softwareModuleTypeId) {
final SoftwareModuleType foundType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundType), HttpStatus.OK);
}
/**
* Handles the DELETE request for a single software module type within SP.
*
* @param softwareModuleTypeId
* the ID of the module to retrieve
* @return status OK if delete as sucessfull.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleTypeId}")
public ResponseEntity<Void> deleteSoftwareModuleType(@PathVariable final Long softwareModuleTypeId) {
@Override
public ResponseEntity<Void> deleteSoftwareModuleType(final Long softwareModuleTypeId) {
final SoftwareModuleType module = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
softwareManagement.deleteSoftwareModuleType(module);
this.softwareManagement.deleteSoftwareModuleType(module);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the PUT request of updating a software module type within SP.
*
* @param softwareModuleTypeId
* the ID of the software module in the URL
* @param restSoftwareModuleType
* the module type to be updated.
* @return status OK if update is successful
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleTypeId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<SoftwareModuleTypeRest> updateSoftwareModuleType(
@PathVariable final Long softwareModuleTypeId,
@RequestBody final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType) {
@Override
public ResponseEntity<SoftwareModuleTypeRest> updateSoftwareModuleType(final Long softwareModuleTypeId,
final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType) {
final SoftwareModuleType type = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
// only description can be modified
@@ -163,27 +94,15 @@ public class SoftwareModuleTypeResource {
type.setDescription(restSoftwareModuleType.getDescription());
}
final SoftwareModuleType updatedSoftwareModuleType = softwareManagement.updateSoftwareModuleType(type);
final SoftwareModuleType updatedSoftwareModuleType = this.softwareManagement.updateSoftwareModuleType(type);
return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(updatedSoftwareModuleType), HttpStatus.OK);
}
/**
* Handles the POST request of creating new {@link SoftwareModuleType}s
* within SP. The request body must always be a list of types.
*
* @param softwareModuleTypes
* the modules to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created but without ResponseBody. 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 })
@Override
public ResponseEntity<SoftwareModuleTypesRest> createSoftwareModuleTypes(
@RequestBody final List<SoftwareModuleTypeRequestBodyPost> softwareModuleTypes) {
final List<SoftwareModuleTypeRequestBodyPost> softwareModuleTypes) {
final List<SoftwareModuleType> createdSoftwareModules = softwareManagement
final List<SoftwareModuleType> createdSoftwareModules = this.softwareManagement
.createSoftwareModuleTypes(SoftwareModuleTypeMapper.smFromRequest(softwareModuleTypes));
return new ResponseEntity<>(SoftwareModuleTypeMapper.toTypesResponse(createdSoftwareModules),
@@ -191,7 +110,7 @@ public class SoftwareModuleTypeResource {
}
private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) {
final SoftwareModuleType module = softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId);
final SoftwareModuleType module = this.softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId);
if (module == null) {
throw new EntityNotFoundException(
"SoftwareModuleType with Id {" + softwareModuleTypeId + "} does not exist");

View File

@@ -17,6 +17,8 @@ import java.util.List;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi;
import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRest;
import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest;
@@ -53,9 +55,9 @@ final class TagMapper {
mapTag(response, targetTag);
response.add(linkTo(methodOn(TargetTagResource.class).getTargetTag(targetTag.getId())).withRel("self"));
response.add(linkTo(methodOn(TargetTagRestApi.class).getTargetTag(targetTag.getId())).withRel("self"));
response.add(linkTo(methodOn(TargetTagResource.class).getAssignedTargets(targetTag.getId()))
response.add(linkTo(methodOn(TargetTagRestApi.class).getAssignedTargets(targetTag.getId()))
.withRel("assignedTargets"));
return response;
@@ -83,12 +85,11 @@ final class TagMapper {
mapTag(response, distributionSetTag);
response.add(
linkTo(methodOn(DistributionSetTagResource.class).getDistributionSetTag(distributionSetTag.getId()))
.withRel("self"));
response.add(linkTo(methodOn(DistributionSetTagRestApi.class).getDistributionSetTag(distributionSetTag.getId()))
.withRel("self"));
response.add(linkTo(
methodOn(DistributionSetTagResource.class).getAssignedDistributionSets(distributionSetTag.getId()))
methodOn(DistributionSetTagRestApi.class).getAssignedDistributionSets(distributionSetTag.getId()))
.withRel("assignedDistributionSets"));
return response;

View File

@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo.PollStatus;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.rest.resource.api.TargetRestApi;
import org.eclipse.hawkbit.rest.resource.model.PollStatusRest;
import org.eclipse.hawkbit.rest.resource.model.action.ActionRest;
import org.eclipse.hawkbit.rest.resource.model.action.ActionStatusRest;
@@ -45,18 +46,18 @@ final public class TargetMapper {
/**
* Add links to a target response.
*
*
* @param response
* the target response
*/
public static void addTargetLinks(final TargetRest response) {
response.add(linkTo(methodOn(TargetResource.class).getAssignedDistributionSet(response.getControllerId()))
response.add(linkTo(methodOn(TargetRestApi.class).getAssignedDistributionSet(response.getControllerId()))
.withRel(RestConstants.TARGET_V1_ASSIGNED_DISTRIBUTION_SET));
response.add(linkTo(methodOn(TargetResource.class).getInstalledDistributionSet(response.getControllerId()))
response.add(linkTo(methodOn(TargetRestApi.class).getInstalledDistributionSet(response.getControllerId()))
.withRel(RestConstants.TARGET_V1_INSTALLED_DISTRIBUTION_SET));
response.add(linkTo(methodOn(TargetResource.class).getAttributes(response.getControllerId()))
response.add(linkTo(methodOn(TargetRestApi.class).getAttributes(response.getControllerId()))
.withRel(RestConstants.TARGET_V1_ATTRIBUTES));
response.add(linkTo(methodOn(TargetResource.class).getActionHistory(response.getControllerId(), 0,
response.add(linkTo(methodOn(TargetRestApi.class).getActionHistory(response.getControllerId(), 0,
RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE,
ActionFields.ID.getFieldName() + ":" + SortDirection.DESC, null))
.withRel(RestConstants.TARGET_V1_ACTIONS));
@@ -64,7 +65,7 @@ final public class TargetMapper {
/**
* Add the pollstatus to a target response.
*
*
* @param target
* the target
* @param targetRest
@@ -85,7 +86,7 @@ final public class TargetMapper {
/**
* Create a response which includes links and pollstatus for all targets.
*
*
* @param targets
* the targets
* @return the response
@@ -105,7 +106,7 @@ final public class TargetMapper {
/**
* Create a response for targets.
*
*
* @param targets
* list of targets
* @return the response
@@ -123,7 +124,7 @@ final public class TargetMapper {
/**
* Create a response for target.
*
*
* @param target
* the target
* @return the response
@@ -163,7 +164,7 @@ final public class TargetMapper {
targetRest.setInstalledAt(installationDate);
}
targetRest.add(linkTo(methodOn(TargetResource.class).getTarget(target.getControllerId())).withRel("self"));
targetRest.add(linkTo(methodOn(TargetRestApi.class).getTarget(target.getControllerId())).withRel("self"));
return targetRest;
}
@@ -210,7 +211,7 @@ final public class TargetMapper {
RestModelMapper.mapBaseToBase(result, action);
result.add(linkTo(methodOn(TargetResource.class).getAction(targetId, action.getId())).withRel("self"));
result.add(linkTo(methodOn(TargetRestApi.class).getAction(targetId, action.getId())).withRel("self"));
return result;
}

View File

@@ -20,13 +20,14 @@ import org.eclipse.hawkbit.repository.ActionStatusFields;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi;
import org.eclipse.hawkbit.rest.resource.api.TargetRestApi;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.rest.resource.model.action.ActionPagedList;
import org.eclipse.hawkbit.rest.resource.model.action.ActionRest;
@@ -47,25 +48,15 @@ import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
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;
import org.springframework.web.bind.annotation.RestController;
/**
* REST Resource handling target CRUD operations.
*
*
*
*
*/
@RestController
@RequestMapping(RestConstants.TARGET_V1_REQUEST_MAPPING)
public class TargetResource {
public class TargetResource implements TargetRestApi {
private static final Logger LOG = LoggerFactory.getLogger(TargetResource.class);
@Autowired
@@ -74,18 +65,8 @@ public class TargetResource {
@Autowired
private DeploymentManagement deploymentManagement;
/**
* Handles the GET request of retrieving a single target within SP.
*
* @param targetId
* the ID of the target to retrieve
* @return a single target with status OK.
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetRest> getTarget(@PathVariable final String targetId) {
@Override
public ResponseEntity<TargetRest> getTarget(final String targetId) {
final Target findTarget = findTargetWithExceptionIfNotFound(targetId);
// to single response include poll status
final TargetRest response = TargetMapper.toResponse(findTarget);
@@ -95,31 +76,9 @@ public class TargetResource {
return new ResponseEntity<>(response, HttpStatus.OK);
}
/**
* Handles the GET request of retrieving all targets within SP.
*
* @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 })
public ResponseEntity<TargetPagedList> getTargets(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TargetPagedList> getTargets(final int pagingOffsetParam, final int pagingLimitParam,
final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -129,58 +88,29 @@ public class TargetResource {
final Slice<Target> findTargetsAll;
final Long countTargetsAll;
if (rsqlParam != null) {
final Page<Target> findTargetPage = targetManagement
final Page<Target> findTargetPage = this.targetManagement
.findTargetsAll(RSQLUtility.parse(rsqlParam, TargetFields.class), pageable);
countTargetsAll = findTargetPage.getTotalElements();
findTargetsAll = findTargetPage;
} else {
findTargetsAll = targetManagement.findTargetsAll(pageable);
countTargetsAll = targetManagement.countTargetsAll();
findTargetsAll = this.targetManagement.findTargetsAll(pageable);
countTargetsAll = this.targetManagement.countTargetsAll();
}
final List<TargetRest> rest = TargetMapper.toResponse(findTargetsAll.getContent());
return new ResponseEntity<>(new TargetPagedList(rest, countTargetsAll), HttpStatus.OK);
}
/**
* Handles the POST request of creating new targets within SP. The request
* body must always be a list of targets. The requests is delegating to the
* {@link TargetManagement#createTarget(Iterable)}.
*
* @param targets
* the targets to be created.
* @return In case all targets could successful created the ResponseEntity
* with status code 201 with a list of successfully created
* entities. 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 })
public ResponseEntity<TargetsRest> createTargets(@RequestBody final List<TargetRequestBody> targets) {
@Override
public ResponseEntity<TargetsRest> createTargets(final List<TargetRequestBody> targets) {
LOG.debug("creating {} targets", targets.size());
final Iterable<Target> createdTargets = targetManagement.createTargets(TargetMapper.fromRequest(targets));
final Iterable<Target> createdTargets = this.targetManagement.createTargets(TargetMapper.fromRequest(targets));
LOG.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED);
return new ResponseEntity<>(TargetMapper.toResponse(createdTargets), HttpStatus.CREATED);
}
/**
* Handles the PUT request of updating a target within SP. 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 targetId
* the path parameter which contains the ID of the target
* @param targetRest
* the request body which contains the fields which should be
* updated, fields which are not given are ignored for the
* udpate.
* @return the updated target response which contains all fields also fields
* which have not updated
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{targetId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetRest> updateTarget(@PathVariable final String targetId,
@RequestBody final TargetRequestBody targetRest) {
@Override
public ResponseEntity<TargetRest> updateTarget(final String targetId, final TargetRequestBody targetRest) {
final Target existingTarget = findTargetWithExceptionIfNotFound(targetId);
LOG.debug("updating target {}", existingTarget.getId());
if (targetRest.getDescription() != null) {
@@ -189,42 +119,21 @@ public class TargetResource {
if (targetRest.getName() != null) {
existingTarget.setName(targetRest.getName());
}
final Target updateTarget = targetManagement.updateTarget(existingTarget);
final Target updateTarget = this.targetManagement.updateTarget(existingTarget);
return new ResponseEntity<>(TargetMapper.toResponse(updateTarget), HttpStatus.OK);
}
/**
* Handles the DELETE request of deleting a target within SP.
*
* @param targetId
* the ID of the target to be deleted
* @return If the given targetId could exists and could be deleted Http OK.
* In any failure the JsonResponseExceptionHandler is handling the
* response.
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> deleteTarget(@PathVariable final String targetId) {
@Override
public ResponseEntity<Void> deleteTarget(final String targetId) {
final Target target = findTargetWithExceptionIfNotFound(targetId);
targetManagement.deleteTargets(target.getId());
this.targetManagement.deleteTargets(target.getId());
LOG.debug("{} target deleted, return status {}", targetId, HttpStatus.OK);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the GET request of retrieving the attributes of a specific
* target.
*
* @param targetId
* the ID of the target to retrieve the attributes.
* @return the target attributes as map response with status OK
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/attributes", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TargetAttributes> getAttributes(@PathVariable final String targetId) {
@Override
public ResponseEntity<TargetAttributes> getAttributes(final String targetId) {
final Target foundTarget = findTargetWithExceptionIfNotFound(targetId);
final Map<String, String> controllerAttributes = foundTarget.getTargetInfo().getControllerAttributes();
if (controllerAttributes.isEmpty()) {
@@ -237,36 +146,9 @@ public class TargetResource {
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* Handles the GET request of retrieving the {@link Action}s of a specific
* target.
*
* @param targetId
* to load actions for
* @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=status==pending}
* @return a list of all {@link Action}s 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, value = "/{targetId}/actions", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionPagedList> getActionHistory(@PathVariable final String targetId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<ActionPagedList> getActionHistory(final String targetId, final int pagingOffsetParam,
final int pagingLimitParam, final String sortParam, final String rsqlParam) {
final Target foundTarget = findTargetWithExceptionIfNotFound(targetId);
@@ -279,11 +161,11 @@ public class TargetResource {
final Long totalActionCount;
if (rsqlParam != null) {
final Specification<Action> parse = RSQLUtility.parse(rsqlParam, ActionFields.class);
activeActions = deploymentManagement.findActionsByTarget(parse, foundTarget, pageable);
totalActionCount = deploymentManagement.countActionsByTarget(parse, foundTarget);
activeActions = this.deploymentManagement.findActionsByTarget(parse, foundTarget, pageable);
totalActionCount = this.deploymentManagement.countActionsByTarget(parse, foundTarget);
} else {
activeActions = deploymentManagement.findActionsByTarget(foundTarget, pageable);
totalActionCount = deploymentManagement.countActionsByTarget(foundTarget);
activeActions = this.deploymentManagement.findActionsByTarget(foundTarget, pageable);
totalActionCount = this.deploymentManagement.countActionsByTarget(foundTarget);
}
return new ResponseEntity<>(
@@ -291,20 +173,8 @@ public class TargetResource {
HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a specific {@link Action}s of a
* specific {@link Target}.
*
* @param targetId
* to load the action for
* @param actionId
* to load
* @return the action
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionRest> getAction(@PathVariable final String targetId,
@PathVariable final Long actionId) {
@Override
public ResponseEntity<ActionRest> getAction(final String targetId, final Long actionId) {
final Target target = findTargetWithExceptionIfNotFound(targetId);
final Action action = findActionWithExceptionIfNotFound(actionId);
@@ -317,14 +187,14 @@ public class TargetResource {
if (!action.isCancelingOrCanceled()) {
result.add(linkTo(
methodOn(DistributionSetResource.class).getDistributionSet(action.getDistributionSet().getId()))
methodOn(DistributionSetRestApi.class).getDistributionSet(action.getDistributionSet().getId()))
.withRel("distributionset"));
} else if (action.isCancelingOrCanceled()) {
result.add(linkTo(methodOn(TargetResource.class).getAction(targetId, action.getId()))
result.add(linkTo(methodOn(TargetRestApi.class).getAction(targetId, action.getId()))
.withRel(RestConstants.TARGET_V1_CANCELED_ACTION));
}
result.add(linkTo(methodOn(TargetResource.class).getActionStatusList(targetId, action.getId(), 0,
result.add(linkTo(methodOn(TargetRestApi.class).getActionStatusList(targetId, action.getId(), 0,
RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE,
ActionStatusFields.ID.getFieldName() + ":" + SortDirection.DESC))
.withRel(RestConstants.TARGET_V1_ACTION_STATUS));
@@ -332,32 +202,16 @@ public class TargetResource {
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* Handles the DELETE request of canceling an specific {@link Action}s of a
* specific {@link Target}.
*
* @param targetId
* the ID of the target in the URL path parameter
* @param actionId
* the ID of the action in the URL path parameter
* @param force
* optional parameter, which indicates a force cancel
* @return status no content in case cancellation was successful
* @throws CancelActionNotAllowedException
* if the given action is not active and cannot be canceled.
* @throws EntityNotFoundException
* if the target or the action is not found
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}/actions/{actionId}")
public ResponseEntity<Void> cancelAction(@PathVariable final String targetId, @PathVariable final Long actionId,
@Override
public ResponseEntity<Void> cancelAction(final String targetId, final Long actionId,
@RequestParam(required = false, defaultValue = "false") final boolean force) {
final Target target = findTargetWithExceptionIfNotFound(targetId);
final Action action = findActionWithExceptionIfNotFound(actionId);
if (force) {
deploymentManagement.forceQuitAction(action, target);
this.deploymentManagement.forceQuitAction(action, target);
} else {
deploymentManagement.cancelAction(action, target);
this.deploymentManagement.cancelAction(action, target);
}
// both functions will throw an exception, when action is in wrong
// state, which is mapped by ResponseExceptionHandler.
@@ -365,35 +219,9 @@ public class TargetResource {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
/**
* Handles the GET request of retrieving the {@link ActionStatus}s of a
* specific target and action.
*
* @param targetId
* of the the action
* @param actionId
* of the status we are intend to load
* @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}
* @return a list of all {@link ActionStatus}s 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, value = "/{targetId}/actions/{actionId}/status", produces = {
"application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ActionStatusPagedList> getActionStatusList(@PathVariable final String targetId,
@PathVariable final Long actionId,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam) {
@Override
public ResponseEntity<ActionStatusPagedList> getActionStatusList(final String targetId, final Long actionId,
final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) {
final Target target = findTargetWithExceptionIfNotFound(targetId);
@@ -407,7 +235,7 @@ public class TargetResource {
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam);
final Page<ActionStatus> statusList = deploymentManagement.findActionStatusMessagesByActionInDescOrder(
final Page<ActionStatus> statusList = this.deploymentManagement.findActionStatusMessagesByActionInDescOrder(
new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true);
return new ResponseEntity<>(
@@ -417,20 +245,8 @@ public class TargetResource {
}
/**
* Handles the GET request of retrieving the assigned distribution set of an
* specific target.
*
* @param targetId
* 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. "{}")
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/assignedDS", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getAssignedDistributionSet(@PathVariable final String targetId) {
@Override
public ResponseEntity<DistributionSetRest> getAssignedDistributionSet(final String targetId) {
final Target findTarget = findTargetWithExceptionIfNotFound(targetId);
final DistributionSetRest distributionSetRest = DistributionSetMapper
.toResponse(findTarget.getAssignedDistributionSet());
@@ -443,28 +259,14 @@ public class TargetResource {
return new ResponseEntity<>(distributionSetRest, retStatus);
}
/**
* Changes the assigned distribution set of a target.
*
* @param targetId
* of the target to change
* @param dsId
* of the distributionset that is to be assigned
* @return {@link HttpStatus#OK}
*
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*
*/
@RequestMapping(method = RequestMethod.POST, value = "/{targetId}/assignedDS", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<Void> postAssignedDistributionSet(@PathVariable final String targetId,
@RequestBody final DistributionSetAssigmentRest dsId) {
@Override
public ResponseEntity<Void> postAssignedDistributionSet(final String targetId,
final DistributionSetAssigmentRest dsId) {
findTargetWithExceptionIfNotFound(targetId);
final ActionType type = (dsId.getType() != null)
? RestResourceConversionHelper.convertActionType(dsId.getType()) : ActionType.FORCED;
final Iterator<Target> changed = deploymentManagement
final Iterator<Target> changed = this.deploymentManagement
.assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), targetId).getAssignedTargets()
.iterator();
if (changed.hasNext()) {
@@ -477,20 +279,8 @@ public class TargetResource {
}
/**
* Handles the GET request of retrieving the installed distribution set of
* an specific target.
*
* @param targetId
* the ID of the target to retrieve
* @return the assigned installed set with status OK, if none is installed
* than {@code null} content (e.g. "{}")
* @throws EntityNotFoundException
* in case no target with the given {@code targetId} exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetId}/installedDS", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<DistributionSetRest> getInstalledDistributionSet(@PathVariable final String targetId) {
@Override
public ResponseEntity<DistributionSetRest> getInstalledDistributionSet(final String targetId) {
final Target findTarget = findTargetWithExceptionIfNotFound(targetId);
final DistributionSetRest distributionSetRest = DistributionSetMapper
.toResponse(findTarget.getTargetInfo().getInstalledDistributionSet());
@@ -504,7 +294,7 @@ public class TargetResource {
}
private Target findTargetWithExceptionIfNotFound(final String targetId) {
final Target findTarget = targetManagement.findTargetByControllerID(targetId);
final Target findTarget = this.targetManagement.findTargetByControllerID(targetId);
if (findTarget == null) {
throw new EntityNotFoundException("Target with Id {" + targetId + "} does not exist");
}
@@ -512,7 +302,7 @@ public class TargetResource {
}
private Action findActionWithExceptionIfNotFound(final Long actionId) {
final Action findAction = deploymentManagement.findAction(actionId);
final Action findAction = this.deploymentManagement.findAction(actionId);
if (findAction == null) {
throw new EntityNotFoundException("Action with Id {" + actionId + "} does not exist");
}

View File

@@ -11,8 +11,6 @@ package org.eclipse.hawkbit.rest.resource;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
@@ -21,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssigmentResult;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi;
import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody;
import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList;
import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut;
@@ -36,13 +35,8 @@ 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.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;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -50,10 +44,8 @@ import org.springframework.web.bind.annotation.RestController;
*
*/
@RestController
@RequestMapping(RestConstants.TARGET_TAG_V1_REQUEST_MAPPING)
public class TargetTagResource {
public class TargetTagResource implements TargetTagRestApi {
private static final Logger LOG = LoggerFactory.getLogger(TargetTagResource.class);
private static final String TARGET_TAG_TAGERTS_REQUEST_MAPPING = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING;
@Autowired
private TagManagement tagManagement;
@@ -61,34 +53,9 @@ public class TargetTagResource {
@Autowired
private TargetManagement targetManagement;
@Autowired
private EntityManager entityManager;
/**
* Handles the GET request of retrieving all target tags.
*
* @param pagingOffsetParam
* the offset of list of target tags 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 target tags 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 })
public ResponseEntity<TagPagedList> getTargetTags(
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam,
@RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) {
@Override
public ResponseEntity<TagPagedList> getTargetTags(final int pagingOffsetParam, final int pagingLimitParam,
final String sortParam, final String rsqlParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
@@ -98,11 +65,11 @@ public class TargetTagResource {
final Slice<TargetTag> findTargetsAll;
final Long countTargetsAll;
if (rsqlParam == null) {
findTargetsAll = tagManagement.findAllTargetTags(pageable);
countTargetsAll = tagManagement.countTargetTags();
findTargetsAll = this.tagManagement.findAllTargetTags(pageable);
countTargetsAll = this.tagManagement.countTargetTags();
} else {
final Page<TargetTag> findTargetPage = tagManagement
final Page<TargetTag> findTargetPage = this.tagManagement
.findAllTargetTags(RSQLUtility.parse(rsqlParam, TagFields.class), pageable);
countTargetsAll = findTargetPage.getTotalElements();
findTargetsAll = findTargetPage;
@@ -113,127 +80,57 @@ public class TargetTagResource {
return new ResponseEntity<>(new TagPagedList(rest, countTargetsAll), HttpStatus.OK);
}
/**
* Handles the GET request of retrieving a single target tag.
*
* @param targetTagId
* the ID of the target tag to retrieve
*
* @return a single target tag with status OK.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{targetTagId}", produces = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> getTargetTag(@PathVariable final Long targetTagId) {
@Override
public ResponseEntity<TagRest> getTargetTag(final Long targetTagId) {
final TargetTag tag = findTargetTagById(targetTagId);
return new ResponseEntity<>(TagMapper.toResponse(tag), HttpStatus.OK);
}
/**
* Handles the POST request of creating new target tag. The request body
* must always be a list of tags.
*
* @param tags
* the target tags to be created.
* @return In case all modules could successful created the ResponseEntity
* with status code 201 - Created. The Response Body are the created
* target tags but without ResponseBody.
*/
@RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
@Override
public ResponseEntity<TagsRest> createTargetTags(@RequestBody final List<TagRequestBodyPut> tags) {
LOG.debug("creating {} target tags", tags.size());
final List<TargetTag> createdTargetTags = tagManagement
final List<TargetTag> createdTargetTags = this.tagManagement
.createTargetTags(TagMapper.mapTargeTagFromRequest(tags));
return new ResponseEntity<>(TagMapper.toResponse(createdTargetTags), HttpStatus.CREATED);
}
/**
*
* Handles the PUT request of updating a single targetr tag.
*
* @param targetTagId
* the ID of the target tag
* @param restTargetTagRest
* the the request body to be updated
* @return status OK if update is successful and the updated target tag.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.PUT, value = "/{targetTagId}", consumes = { "application/hal+json",
MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<TagRest> updateTagretTag(@PathVariable final Long targetTagId,
@RequestBody final TagRequestBodyPut restTargetTagRest) {
@Override
public ResponseEntity<TagRest> updateTagretTag(final Long targetTagId, final TagRequestBodyPut restTargetTagRest) {
LOG.debug("update {} target tag", restTargetTagRest);
final TargetTag targetTag = findTargetTagById(targetTagId);
TagMapper.updateTag(restTargetTagRest, targetTag);
final TargetTag updateTargetTag = tagManagement.updateTargetTag(targetTag);
final TargetTag updateTargetTag = this.tagManagement.updateTargetTag(targetTag);
LOG.debug("target tag updated");
return new ResponseEntity<>(TagMapper.toResponse(updateTargetTag), HttpStatus.OK);
}
/**
* Handles the DELETE request for a single target tag.
*
* @param targetTagId
* the ID of the target tag
* @return status OK if delete as successfully.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*
*/
@RequestMapping(method = RequestMethod.DELETE, value = "/{targetTagId}")
public ResponseEntity<Void> deleteTargetTag(@PathVariable final Long targetTagId) {
@Override
public ResponseEntity<Void> deleteTargetTag(final Long targetTagId) {
LOG.debug("Delete {} target tag", targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId);
tagManagement.deleteTargetTag(targetTag.getName());
this.tagManagement.deleteTargetTag(targetTag.getName());
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the GET request of retrieving all assigned targets by the given
* tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
*
* @return the list of assigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.GET, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<TargetsRest> getAssignedTargets(@PathVariable final Long targetTagId) {
@Override
public ResponseEntity<TargetsRest> getAssignedTargets(final Long targetTagId) {
final TargetTag targetTag = findTargetTagById(targetTagId);
return new ResponseEntity<>(TargetMapper.toResponseWithLinksAndPollStatus(targetTag.getAssignedToTargets()),
HttpStatus.OK);
}
/**
* Handles the POST request to toggle the assignment of targets by the given
* tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be toggled
*
* @return the list of assigned targets and unassigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.POST, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/toggleTagAssignment")
public ResponseEntity<TargetTagAssigmentResultRest> toggleTagAssignment(@PathVariable final Long targetTagId,
@RequestBody final List<AssignedTargetRequestBody> assignedTargetRequestBodies) {
@Override
public ResponseEntity<TargetTagAssigmentResultRest> toggleTagAssignment(final Long targetTagId,
final List<AssignedTargetRequestBody> assignedTargetRequestBodies) {
LOG.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId);
final TargetTagAssigmentResult assigmentResult = targetManagement
final TargetTagAssigmentResult assigmentResult = this.targetManagement
.toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName());
final TargetTagAssigmentResultRest tagAssigmentResultRest = new TargetTagAssigmentResultRest();
@@ -242,71 +139,38 @@ public class TargetTagResource {
return new ResponseEntity<>(tagAssigmentResultRest, HttpStatus.OK);
}
/**
* Handles the POST request to assign targets to the given tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be assigned
*
* @return the list of assigned targets.
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.POST, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<TargetsRest> assignTargets(@PathVariable final Long targetTagId,
@RequestBody final List<AssignedTargetRequestBody> assignedTargetRequestBodies) {
@Override
public ResponseEntity<TargetsRest> assignTargets(final Long targetTagId,
final List<AssignedTargetRequestBody> assignedTargetRequestBodies) {
LOG.debug("Assign Targets {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId);
final List<Target> assignedTarget = targetManagement
final List<Target> assignedTarget = this.targetManagement
.assignTag(findTargetControllerIds(assignedTargetRequestBodies), targetTag);
return new ResponseEntity<>(TargetMapper.toResponseWithLinksAndPollStatus(assignedTarget), HttpStatus.OK);
}
/**
* Handles the DELETE request to unassign all targets from the given tag id.
*
* @param targetTagId
* the ID of the target tag to retrieve
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING)
public ResponseEntity<Void> unassignTargets(@PathVariable final Long targetTagId) {
@Override
public ResponseEntity<Void> unassignTargets(final Long targetTagId) {
LOG.debug("Unassign all Targets for target tag {}", targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId);
if (targetTag.getAssignedToTargets() == null) {
LOG.debug("No assigned targets found");
return new ResponseEntity<>(HttpStatus.OK);
}
targetManagement.unAssignAllTargetsByTag(targetTag);
this.targetManagement.unAssignAllTargetsByTag(targetTag);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* Handles the DELETE request to unassign one target from the given tag id.
*
* @param targetTagId
* the ID of the target tag
* @param controllerId
* the ID of the target to unassign
* @return http status code
* @throws EntityNotFoundException
* in case the given {@code targetTagId} doesn't exists.
*/
@RequestMapping(method = RequestMethod.DELETE, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/{controllerId}")
public ResponseEntity<Void> unassignTarget(@PathVariable final Long targetTagId,
@PathVariable final String controllerId) {
@Override
public ResponseEntity<Void> unassignTarget(final Long targetTagId, final String controllerId) {
LOG.debug("Unassign target {} for target tag {}", controllerId, targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId);
targetManagement.unAssignTag(controllerId, targetTag);
this.targetManagement.unAssignTag(controllerId, targetTag);
return new ResponseEntity<>(HttpStatus.OK);
}
private TargetTag findTargetTagById(final Long targetTagId) {
final TargetTag tag = tagManagement.findTargetTagById(targetTagId);
final TargetTag tag = this.tagManagement.findTargetTagById(targetTagId);
if (tag == null) {
throw new EntityNotFoundException("Target Tag with Id {" + targetTagId + "} does not exist");
}

View File

@@ -75,7 +75,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
private SpringViewProvider viewProvider;
@Autowired
private ApplicationContext context;
private transient ApplicationContext context;
@Autowired
private I18N i18n;
@@ -89,13 +89,13 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
private ErrorView errorview;
@Autowired
protected EventBus.SessionEventBus eventBus;
protected transient EventBus.SessionEventBus eventBus;
/**
* An {@link com.google.common.eventbus.EventBus} subscriber which
* subscribes {@link EntityEvent} from the repository to dispatch these
* events to the UI {@link SessionEventBus}.
*
*
* @param event
* the entity event which has been published from the repository
*/
@@ -103,21 +103,28 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
@AllowConcurrentEvents
public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) {
final VaadinSession session = getSession();
if (session != null && session.getState() == State.OPEN) {
final WrappedSession wrappedSession = session.getSession();
if (wrappedSession != null) {
final SecurityContext userContext = (SecurityContext) wrappedSession
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (eventSecurityCheck(userContext, event)) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
try {
access(new DispatcherRunnable(eventBus, session, userContext, event));
} finally {
SecurityContextHolder.setContext(oldContext);
}
}
}
if (session == null || session.getState() != State.OPEN) {
return;
}
final WrappedSession wrappedSession = session.getSession();
if (wrappedSession == null) {
return;
}
final SecurityContext userContext = (SecurityContext) wrappedSession
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (!eventSecurityCheck(userContext, event)) {
return;
}
final SecurityContext oldContext = SecurityContextHolder.getContext();
try {
access(new DispatcherRunnable(eventBus, session, userContext, event));
} finally {
SecurityContextHolder.setContext(oldContext);
}
}
protected boolean eventSecurityCheck(final SecurityContext userContext,
@@ -134,7 +141,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
/*
* (non-Javadoc)
*
*
* @see
* com.vaadin.server.ClientConnector.DetachListener#detach(com.vaadin.server
* .ClientConnector. DetachEvent)
@@ -225,7 +232,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
/**
* Get Specific Locale.
*
*
* @param availableLocalesInApp
* as set
* @return String as preferred locale

View File

@@ -44,9 +44,9 @@ import com.vaadin.ui.themes.ValoTheme;
/**
* Abstract layout of confirm actions window.
*
*
*
*
*
*/
@SpringComponent
@ViewScope
@@ -84,13 +84,13 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.common.confirmwindow.layout.
* AbstractConfirmationWindowLayout# getConfimrationTabs()
*/
@Override
protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<String, ConfirmationTab>();
final Map<String, ConfirmationTab> tabs = new HashMap<>();
if (!artifactUploadState.getDeleteSofwareModules().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
}
@@ -145,7 +145,7 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
/**
* Get SWModule table container.
*
*
* @return IndexedContainer
*/
@SuppressWarnings("unchecked")
@@ -153,9 +153,8 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
final IndexedContainer swcontactContainer = new IndexedContainer();
swcontactContainer.addContainerProperty("SWModuleId", String.class, "");
swcontactContainer.addContainerProperty(SW_MODULE_NAME_MSG, String.class, "");
Item item = null;
for (final Long swModuleID : artifactUploadState.getDeleteSofwareModules().keySet()) {
item = swcontactContainer.addItem(swModuleID);
final Item item = swcontactContainer.addItem(swModuleID);
item.getItemProperty("SWModuleId").setValue(swModuleID.toString());
item.getItemProperty(SW_MODULE_NAME_MSG)
.setValue(artifactUploadState.getDeleteSofwareModules().get(swModuleID));
@@ -197,7 +196,7 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
for (final CustomFile customFile : artifactUploadState.getFileSelected()) {
final String swNameVersion = HawkbitCommonUtil.getFormattedNameVersion(
customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion());
if (HawkbitCommonUtil.bothSame(deleteSoftwareNameVersion, swNameVersion)) {
if (deleteSoftwareNameVersion != null && deleteSoftwareNameVersion.equals(swNameVersion)) {
tobeRemoved.add(customFile);
}
}

View File

@@ -38,13 +38,13 @@ public class ArtifactUploadState implements Serializable {
private final Map<Long, String> deleteSofwareModules = new HashMap<>();
private final Set<CustomFile> fileSelected = new HashSet<CustomFile>();
private final Set<CustomFile> fileSelected = new HashSet<>();
private Long selectedBaseSwModuleId;
private SoftwareModule selectedBaseSoftwareModule;
private final Map<String, SoftwareModule> baseSwModuleList = new HashMap<String, SoftwareModule>();
private final Map<String, SoftwareModule> baseSwModuleList = new HashMap<>();
private Set<Long> selectedSoftwareModules = Collections.emptySet();
@@ -60,7 +60,7 @@ public class ArtifactUploadState implements Serializable {
/**
* Set software.
*
*
* @return
*/
public SoftwareModuleFilters getSoftwareModuleFilters() {
@@ -85,7 +85,7 @@ public class ArtifactUploadState implements Serializable {
* @return the selectedBaseSwModuleId
*/
public Optional<Long> getSelectedBaseSwModuleId() {
return this.selectedBaseSwModuleId != null ? Optional.of(this.selectedBaseSwModuleId) : Optional.empty();
return selectedBaseSwModuleId != null ? Optional.of(selectedBaseSwModuleId) : Optional.empty();
}
/**
@@ -100,8 +100,7 @@ public class ArtifactUploadState implements Serializable {
* @return the selectedBaseSoftwareModule
*/
public Optional<SoftwareModule> getSelectedBaseSoftwareModule() {
return this.selectedBaseSoftwareModule == null ? Optional.empty()
: Optional.of(this.selectedBaseSoftwareModule);
return selectedBaseSoftwareModule == null ? Optional.empty() : Optional.of(selectedBaseSoftwareModule);
}
/**

View File

@@ -10,8 +10,6 @@ package org.eclipse.hawkbit.ui.artifacts.state;
import java.io.Serializable;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
/**
* Custom file to hold details of uploaded file.
*
@@ -168,36 +166,50 @@ public class CustomFile implements Serializable {
return failureReason;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() { // NOSONAR - as this is generated
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (fileName == null ? 0 : fileName.hashCode());
result = prime * result + ((baseSoftwareModuleName == null) ? 0 : baseSoftwareModuleName.hashCode());
result = prime * result + ((baseSoftwareModuleVersion == null) ? 0 : baseSoftwareModuleVersion.hashCode());
result = prime * result + ((fileName == null) ? 0 : fileName.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof CustomFile)) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CustomFile other = (CustomFile) obj;
return HawkbitCommonUtil.bothSame(fileName, other.fileName)
&& HawkbitCommonUtil.bothSame(baseSoftwareModuleName, other.baseSoftwareModuleName)
&& HawkbitCommonUtil.bothSame(baseSoftwareModuleVersion, other.baseSoftwareModuleVersion);
if (baseSoftwareModuleName == null) {
if (other.baseSoftwareModuleName != null) {
return false;
}
} else if (!baseSoftwareModuleName.equals(other.baseSoftwareModuleName)) {
return false;
}
if (baseSoftwareModuleVersion == null) {
if (other.baseSoftwareModuleVersion != null) {
return false;
}
} else if (!baseSoftwareModuleVersion.equals(other.baseSoftwareModuleVersion)) {
return false;
}
if (fileName == null) {
if (other.fileName != null) {
return false;
}
} else if (!fileName.equals(other.fileName)) {
return false;
}
return true;
}
}

View File

@@ -8,8 +8,6 @@
*/
package org.eclipse.hawkbit.ui.common.filterlayout;
import java.util.Optional;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import com.vaadin.ui.Button;
@@ -17,20 +15,20 @@ import com.vaadin.ui.Button.ClickEvent;
/**
* Abstract Single button click behaviour of filter buttons layout.
*
*
*
*
*
*
*/
public abstract class AbstractFilterSingleButtonClick extends AbstractFilterButtonClickBehaviour {
private static final long serialVersionUID = 478874092615793581L;
private Optional<Button> alreadyClickedButton = Optional.empty();
private Button alreadyClickedButton;
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.layouts.SPFilterButtonClick#
* processFilterButtonClick(com.vaadin.ui. Button.ClickEvent)
*/
@@ -40,18 +38,18 @@ public abstract class AbstractFilterSingleButtonClick extends AbstractFilterButt
if (isButtonUnClicked(clickedButton)) {
/* If same button clicked */
clickedButton.removeStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
alreadyClickedButton = Optional.empty();
alreadyClickedButton = null;
filterUnClicked(clickedButton);
} else if (alreadyClickedButton.isPresent()) {
} else if (alreadyClickedButton != null) {
/* If button clicked and some other button is already clicked */
alreadyClickedButton.get().removeStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
alreadyClickedButton.removeStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
clickedButton.addStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
alreadyClickedButton = Optional.of(clickedButton);
alreadyClickedButton = clickedButton;
filterClicked(clickedButton);
} else {
/* If button clicked and not other button is clicked currently */
clickedButton.addStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
alreadyClickedButton = Optional.of(clickedButton);
alreadyClickedButton = clickedButton;
filterClicked(clickedButton);
}
}
@@ -61,21 +59,19 @@ public abstract class AbstractFilterSingleButtonClick extends AbstractFilterButt
* @return
*/
private boolean isButtonUnClicked(final Button clickedButton) {
return alreadyClickedButton.isPresent() && alreadyClickedButton.get().equals(clickedButton);
return alreadyClickedButton != null && alreadyClickedButton.equals(clickedButton);
}
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.layouts.SPFilterButtonClickBehaviour#
* setDefaultClickedButton(com.vaadin .ui.Button)
*/
@Override
protected void setDefaultClickedButton(final Button button) {
if (button == null) {
alreadyClickedButton = Optional.empty();
} else {
alreadyClickedButton = Optional.of(button);
alreadyClickedButton = button;
if (button != null) {
button.addStyleName(SPUIStyleDefinitions.SP_FILTER_BTN_CLICKED_STYLE);
}
}
@@ -83,7 +79,7 @@ public abstract class AbstractFilterSingleButtonClick extends AbstractFilterButt
/**
* @return the alreadyClickedButton
*/
public Optional<Button> getAlreadyClickedButton() {
public Button getAlreadyClickedButton() {
return alreadyClickedButton;
}
@@ -91,7 +87,7 @@ public abstract class AbstractFilterSingleButtonClick extends AbstractFilterButt
* @param alreadyClickedButton
* the alreadyClickedButton to set
*/
public void setAlreadyClickedButton(final Optional<Button> alreadyClickedButton) {
public void setAlreadyClickedButton(final Button alreadyClickedButton) {
this.alreadyClickedButton = alreadyClickedButton;
}

View File

@@ -32,7 +32,7 @@ import com.vaadin.ui.themes.ValoTheme;
/**
* Abstract class for target/ds tag token layout.
*
*
*
*
*
@@ -47,9 +47,9 @@ public abstract class AbstractTagToken implements Serializable {
protected IndexedContainer container;
protected final Map<Long, TagData> tagDetails = new HashMap<Long, TagData>();
protected final Map<Long, TagData> tagDetails = new HashMap<>();
protected final Map<Long, TagData> tokensAdded = new HashMap<Long, TagData>();
protected final Map<Long, TagData> tokensAdded = new HashMap<>();
protected CssLayout tokenLayout = new CssLayout();
@@ -123,7 +123,7 @@ public abstract class AbstractTagToken implements Serializable {
class CustomTokenField extends TokenField {
private static final long serialVersionUID = 694216966472937436L;
final Container tokenContainer;
Container tokenContainer;
CustomTokenField(final CssLayout cssLayout, final Container tokenContainer) {
super(cssLayout);
@@ -235,9 +235,11 @@ public abstract class AbstractTagToken implements Serializable {
/**
* Tag details.
*
*
*/
public static class TagData {
public static class TagData implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
@@ -247,7 +249,7 @@ public abstract class AbstractTagToken implements Serializable {
/**
* Tag data constructor.
*
*
* @param id
* @param name
* @param color

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.ui.distributions.dstable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -57,7 +58,7 @@ import com.vaadin.ui.Window;
/**
* Distribution set details layout.
*
*
*
*
*/
@@ -153,12 +154,13 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
@SuppressWarnings("unchecked")
private void showUnsavedAssignment() {
Item item;
final Map<DistributionSetIdName, Set<SoftwareModuleIdName>> assignedList = manageDistUIState.getAssignedList();
final Map<DistributionSetIdName, HashSet<SoftwareModuleIdName>> assignedList = manageDistUIState
.getAssignedList();
final Long selectedDistId = manageDistUIState.getLastSelectedDistribution().isPresent()
? manageDistUIState.getLastSelectedDistribution().get().getId() : null;
Set<SoftwareModuleIdName> softwareModuleIdNameList = null;
for (final Map.Entry<DistributionSetIdName, Set<SoftwareModuleIdName>> entry : assignedList.entrySet()) {
for (final Map.Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> entry : assignedList.entrySet()) {
if (entry.getKey().getId().equals(selectedDistId)) {
softwareModuleIdNameList = entry.getValue();
break;
@@ -321,7 +323,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* onEdit(com.vaadin.ui .Button.ClickEvent)
*/
@@ -336,7 +338,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* getEditButtonId()
*/
@@ -347,7 +349,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* onLoadIsSwModuleSelected ()
*/
@@ -359,7 +361,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* onLoadIsTableMaximized ()
*/
@@ -370,7 +372,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* populateDetailsWidget()
*/
@@ -381,7 +383,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* getDefaultCaption()
*/
@@ -392,7 +394,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* addTabs(com.vaadin. ui.TabSheet)
*/
@@ -407,7 +409,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* clearDetails()
*/
@@ -418,7 +420,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* hasEditSoftwareModulePermission()
*/
@@ -507,7 +509,7 @@ public class DistributionSetDetails extends AbstractTableDetailsLayout {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.detailslayout.AbstractTableDetailsLayout#
* getTabSheetId()
*/

View File

@@ -73,7 +73,7 @@ import com.vaadin.ui.UI;
/**
* Distribution set table.
*
*
*
*
*/
@@ -140,7 +140,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.table.AbstractTable#getTableId()
*/
@@ -151,7 +151,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.table.AbstractTable#createContainer(
* )
@@ -160,15 +160,12 @@ public class DistributionSetTable extends AbstractTable {
protected Container createContainer() {
final Map<String, Object> queryConfiguration = prepareQueryConfigFilters();
final BeanQueryFactory<ManageDistBeanQuery> distributionQF = new BeanQueryFactory<ManageDistBeanQuery>(
ManageDistBeanQuery.class);
final BeanQueryFactory<ManageDistBeanQuery> distributionQF = new BeanQueryFactory<>(ManageDistBeanQuery.class);
distributionQF.setQueryConfiguration(queryConfiguration);
final LazyQueryContainer distContainer = new LazyQueryContainer(
return new LazyQueryContainer(
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME),
distributionQF);
return distContainer;
}
private Map<String, Object> prepareQueryConfigFilters() {
@@ -187,7 +184,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.table.AbstractTable#addContainerProperties
* (com.vaadin.data.Container )
*/
@@ -200,7 +197,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.common.table.AbstractTable#
* addCustomGeneratedColumns ()
*/
@@ -213,7 +210,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.common.table.AbstractTable#
* isFirstRowSelectedOnLoad ()
*/
@@ -225,7 +222,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.table.AbstractTable#getItemIdToSelect()
*/
@Override
@@ -238,7 +235,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.table.AbstractTable#onValueChange()
*/
@@ -278,7 +275,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.table.AbstractTable#isMaximized()
*/
@@ -289,7 +286,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.table.AbstractTable#getTableVisibleColumns
* ()
*/
@@ -300,7 +297,7 @@ public class DistributionSetTable extends AbstractTable {
/*
* (non-Javadoc)
*
*
* @see hawkbit.server.ui.common.table.AbstractTable#getTableDropHandler()
*/
@Override
@@ -326,7 +323,7 @@ public class DistributionSetTable extends AbstractTable {
final TableTransferable transferable = (TableTransferable) event.getTransferable();
final Table source = transferable.getSourceComponent();
final Set<Long> softwareModuleSelected = (Set<Long>) source.getValue();
final Set<Long> softwareModulesIdList = new HashSet<Long>();
final Set<Long> softwareModulesIdList = new HashSet<>();
if (!softwareModuleSelected.contains(transferable.getData("itemId"))) {
softwareModulesIdList.add((Long) transferable.getData("itemId"));
@@ -354,11 +351,11 @@ public class DistributionSetTable extends AbstractTable {
final String distVersion = (String) item.getItemProperty("version").getValue();
final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distId, distName, distVersion);
final Map<Long, Set<SoftwareModuleIdName>> map;
final HashMap<Long, HashSet<SoftwareModuleIdName>> map;
if (manageDistUIState.getConsolidatedDistSoftwarewList().containsKey(distributionSetIdName)) {
map = manageDistUIState.getConsolidatedDistSoftwarewList().get(distributionSetIdName);
} else {
map = new HashMap<Long, Set<SoftwareModuleIdName>>();
map = new HashMap<>();
manageDistUIState.getConsolidatedDistSoftwarewList().put(distributionSetIdName, map);
}
@@ -391,7 +388,8 @@ public class DistributionSetTable extends AbstractTable {
}
}
final Set<SoftwareModuleIdName> softwareModules = new HashSet<SoftwareModuleIdName>();
// hashset is seriablizable
final HashSet<SoftwareModuleIdName> softwareModules = new HashSet<>();
map.keySet().forEach(typeId -> softwareModules.addAll(map.get(typeId)));
updateDropedDetails(distributionSetIdName, softwareModules);
@@ -414,8 +412,8 @@ public class DistributionSetTable extends AbstractTable {
* @param softwareModule
* @param softwareModuleIdName
*/
private void handleFirmwareCase(final Map<Long, Set<SoftwareModuleIdName>> map, final SoftwareModule softwareModule,
final SoftwareModuleIdName softwareModuleIdName) {
private void handleFirmwareCase(final Map<Long, HashSet<SoftwareModuleIdName>> map,
final SoftwareModule softwareModule, final SoftwareModuleIdName softwareModuleIdName) {
if (softwareModule.getType().getMaxAssignments() == 1) {
if (!map.containsKey(softwareModule.getType().getId())) {
map.put(softwareModule.getType().getId(), new HashSet<SoftwareModuleIdName>());
@@ -432,8 +430,8 @@ public class DistributionSetTable extends AbstractTable {
* @param softwareModule
* @param softwareModuleIdName
*/
private void handleSoftwareCase(final Map<Long, Set<SoftwareModuleIdName>> map, final SoftwareModule softwareModule,
final SoftwareModuleIdName softwareModuleIdName) {
private void handleSoftwareCase(final Map<Long, HashSet<SoftwareModuleIdName>> map,
final SoftwareModule softwareModule, final SoftwareModuleIdName softwareModuleIdName) {
if (softwareModule.getType().getMaxAssignments() == Integer.MAX_VALUE) {
if (!map.containsKey(softwareModule.getType().getId())) {
map.put(softwareModule.getType().getId(), new HashSet<SoftwareModuleIdName>());
@@ -443,7 +441,7 @@ public class DistributionSetTable extends AbstractTable {
}
private void updateDropedDetails(final DistributionSetIdName distributionSetIdName,
final Set<SoftwareModuleIdName> softwareModules) {
final HashSet<SoftwareModuleIdName> softwareModules) {
LOG.debug("Adding a log to check if distributionSetIdName is null : {} ", distributionSetIdName);
manageDistUIState.getAssignedList().put(distributionSetIdName, softwareModules);
@@ -496,20 +494,20 @@ public class DistributionSetTable extends AbstractTable {
}
private boolean isSoftwareModuleDragged(final Long distId, final SoftwareModule sm) {
for (final Entry<DistributionSetIdName, Set<SoftwareModuleIdName>> entry : manageDistUIState.getAssignedList()
.entrySet()) {
if (distId.equals(entry.getKey().getId())) {
final Set<SoftwareModuleIdName> swModuleIdNames = entry.getValue();
for (final SoftwareModuleIdName swModuleIdName : swModuleIdNames) {
if ((sm.getName().concat(":" + sm.getVersion())).equals(swModuleIdName.getName())) {
notification.displayValidationError(i18n.get("message.software.already.dragged",
HawkbitCommonUtil.concatStrings(":", sm.getName(), sm.getVersion())));
return false;
}
}
for (final Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> entry : manageDistUIState
.getAssignedList().entrySet()) {
if (!distId.equals(entry.getKey().getId())) {
continue;
}
final Set<SoftwareModuleIdName> swModuleIdNames = entry.getValue();
for (final SoftwareModuleIdName swModuleIdName : swModuleIdNames) {
if ((sm.getName().concat(":" + sm.getVersion())).equals(swModuleIdName.getName())) {
notification.displayValidationError(i18n.get("message.software.already.dragged",
HawkbitCommonUtil.concatStrings(":", sm.getName(), sm.getVersion())));
return false;
}
}
}
return true;
}
@@ -573,21 +571,18 @@ public class DistributionSetTable extends AbstractTable {
}
private void addTableStyleGenerator() {
setCellStyleGenerator(new Table.CellStyleGenerator() {
@Override
public String getStyle(final Table source, final Object itemId, final Object propertyId) {
if (propertyId == null) {
// Styling for row
final Item item = getItem(itemId);
final Boolean isComplete = (Boolean) item
.getItemProperty(SPUILabelDefinitions.VAR_IS_DISTRIBUTION_COMPLETE).getValue();
if (!isComplete) {
return SPUIDefinitions.DISABLE_DISTRIBUTION;
}
return null;
} else {
return null;
setCellStyleGenerator((source, itemId, propertyId) -> {
if (propertyId == null) {
// Styling for row
final Item item = getItem(itemId);
final Boolean isComplete = (Boolean) item
.getItemProperty(SPUILabelDefinitions.VAR_IS_DISTRIBUTION_COMPLETE).getValue();
if (!isComplete) {
return SPUIDefinitions.DISABLE_DISTRIBUTION;
}
return null;
} else {
return null;
}
});
}
@@ -612,7 +607,7 @@ public class DistributionSetTable extends AbstractTable {
/**
* DistributionTableFilterEvent.
*
*
* @param event
* as instance of {@link DistributionTableFilterEvent}
*/

View File

@@ -51,9 +51,9 @@ import com.vaadin.ui.UI;
/**
* Distributions footer layout implementation.
*
*
*
*
*
*/
@org.springframework.stereotype.Component
@ViewScope
@@ -94,10 +94,11 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.DeleteActionsLayout#init()
*/
@Override
@PostConstruct
protected void init() {
super.init();
@@ -140,7 +141,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* hasDeletePermission()
@@ -153,7 +154,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* hasUpdatePermission()
@@ -166,7 +167,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getDeleteAreaLabel()
@@ -178,7 +179,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getDeleteAreaId()
@@ -191,7 +192,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getDeleteLayoutAcceptCriteria ()
@@ -204,7 +205,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* processDroppedComponent(com .vaadin.event.dd.DragAndDropEvent)
@@ -248,7 +249,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/**
* Check if distribution set type is selected.
*
*
* @param distTypeName
* @return true if ds type is selected
*/
@@ -276,7 +277,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
private void addInDeleteDistributionList(final Table sourceTable, final TableTransferable transferable) {
@SuppressWarnings("unchecked")
final Set<DistributionSetIdName> distSelected = (Set<DistributionSetIdName>) sourceTable.getValue();
final Set<DistributionSetIdName> distributionIdNameSet = new HashSet<DistributionSetIdName>();
final Set<DistributionSetIdName> distributionIdNameSet = new HashSet<>();
if (!distSelected.contains(transferable.getData(SPUIDefinitions.ITEMID))) {
distributionIdNameSet.add((DistributionSetIdName) transferable.getData(SPUIDefinitions.ITEMID));
} else {
@@ -314,7 +315,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
@SuppressWarnings("unchecked")
final Set<Long> swModuleSelected = (Set<Long>) sourceTable.getValue();
final Set<Long> swModuleIdNameSet = new HashSet<Long>();
final Set<Long> swModuleIdNameSet = new HashSet<>();
if (!swModuleSelected.contains(transferable.getData(SPUIDefinitions.ITEMID))) {
swModuleIdNameSet.add((Long) transferable.getData(SPUIDefinitions.ITEMID));
} else {
@@ -336,7 +337,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
+ manageDistUIState.getDeleteSofwareModulesList().size()
+ manageDistUIState.getDeletedDistributionList().size();
for (final Entry<DistributionSetIdName, Set<SoftwareModuleIdName>> mapEntry : manageDistUIState
for (final Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> mapEntry : manageDistUIState
.getAssignedList().entrySet()) {
count += manageDistUIState.getAssignedList().get(mapEntry.getKey()).size();
}
@@ -345,7 +346,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/**
* DistributionsUIEvent.
*
*
* @param event
* as instance of {@link DistributionsUIEvent}
*/
@@ -357,27 +358,17 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
}
/**
*
* @param source
* @return true if it is distribution table
*/
private boolean isDistributionTable(final Component source) {
return HawkbitCommonUtil.bothSame(source.getId(), SPUIComponetIdProvider.DIST_TABLE_ID);
return SPUIComponetIdProvider.DIST_TABLE_ID.equals(source.getId());
}
/**
*
* @param source
* @return true if it is SoftwareModule table
*/
private boolean isSoftwareModuleTable(final Component source) {
return HawkbitCommonUtil.bothSame(source.getId(), SPUIComponetIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE);
return SPUIComponetIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE.equals(source.getId());
}
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getNoActionsButtonLabel()
@@ -389,7 +380,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getActionsButtonLabel()
@@ -403,7 +394,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* reloadActionCount()
@@ -416,7 +407,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getUnsavedActionsWindowCaption ()
@@ -428,7 +419,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* unsavedActionsWindowClosed()
@@ -444,7 +435,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* getUnsavedActionsWindowContent ()
@@ -457,7 +448,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see
* org.eclipse.hawkbit.server.ui.common.footer.AbstractDeleteActionsLayout#
* hasUnsavedActions()
@@ -490,7 +481,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout#
* hasBulkUploadPermission()
*/
@@ -501,7 +492,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout#
* showBulkUploadWindow()
*/
@@ -514,7 +505,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout#
* restoreBulkUploadStatusCount()
*/
@@ -531,7 +522,7 @@ public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout {
/**
* Check if the distribution set type is default.
*
*
* @param dsTypeName
* distribution set name
* @return true if distribution set type is set default in configuration

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.distributions.footer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -52,9 +53,9 @@ import com.vaadin.ui.themes.ValoTheme;
/**
* Abstract layout of confirm actions window.
*
*
*
*
*
*/
@org.springframework.stereotype.Component
@ViewScope
@@ -107,13 +108,13 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
/*
* (non-Javadoc)
*
*
* @see org.eclipse.hawkbit.server.ui.common.confirmwindow.layout.
* AbstractConfirmationWindowLayout# getConfimrationTabs()
*/
@Override
protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<String, ConfirmationTab>();
final Map<String, ConfirmationTab> tabs = new HashMap<>();
/* Create tab for SW Modules delete */
if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
@@ -190,26 +191,8 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
private void deleteSMAll(final ConfirmationTab tab) {
final Set<Long> swmoduleIds = manageDistUIState.getDeleteSofwareModulesList().keySet();
if (null != manageDistUIState.getAssignedList() && !manageDistUIState.getAssignedList().isEmpty()) {
for (final Entry<DistributionSetIdName, Set<SoftwareModuleIdName>> entryAssignSM : manageDistUIState
.getAssignedList().entrySet()) {
for (final Entry<Long, String> entryDeleteSM : manageDistUIState.getDeleteSofwareModulesList()
.entrySet()) {
final SoftwareModuleIdName smIdName = new SoftwareModuleIdName(entryDeleteSM.getKey(),
entryDeleteSM.getValue());
if (entryAssignSM.getValue().contains(smIdName)) {
entryAssignSM.getValue().remove(smIdName);
assignmnetTab.getTable().removeItem(HawkbitCommonUtil.concatStrings("|||",
entryAssignSM.getKey().getId().toString(), smIdName.getId().toString()));
}
if (entryAssignSM.getValue().isEmpty()) {
manageDistUIState.getAssignedList().remove(entryAssignSM.getKey());
}
}
}
if (manageDistUIState.getAssignedList() == null || manageDistUIState.getAssignedList().isEmpty()) {
removeAssignedSoftwareModules();
}
softwareManagement.deleteSoftwareModules(swmoduleIds);
@@ -221,6 +204,25 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
eventBus.publish(this, SaveActionWindowEvent.DELETE_ALL_SOFWARE);
}
private void removeAssignedSoftwareModules() {
for (final Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> entryAssignSM : manageDistUIState
.getAssignedList().entrySet()) {
for (final Entry<Long, String> entryDeleteSM : manageDistUIState.getDeleteSofwareModulesList().entrySet()) {
final SoftwareModuleIdName smIdName = new SoftwareModuleIdName(entryDeleteSM.getKey(),
entryDeleteSM.getValue());
if (entryAssignSM.getValue().contains(smIdName)) {
entryAssignSM.getValue().remove(smIdName);
assignmnetTab.getTable().removeItem(HawkbitCommonUtil.concatStrings("|||",
entryAssignSM.getKey().getId().toString(), smIdName.getId().toString()));
}
if (entryAssignSM.getValue().isEmpty()) {
manageDistUIState.getAssignedList().remove(entryAssignSM.getKey());
}
}
}
}
private void discardSMAll(final ConfirmationTab tab) {
removeCurrentTab(tab);
manageDistUIState.getDeleteSofwareModulesList().clear();
@@ -230,7 +232,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
/**
* Get SWModule table container.
*
*
* @return IndexedContainer
*/
@SuppressWarnings("unchecked")
@@ -238,9 +240,8 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
final IndexedContainer swcontactContainer = new IndexedContainer();
swcontactContainer.addContainerProperty("SWModuleId", String.class, "");
swcontactContainer.addContainerProperty(SW_MODULE_NAME_MSG, String.class, "");
Item item = null;
for (final Long swModuleID : manageDistUIState.getDeleteSofwareModulesList().keySet()) {
item = swcontactContainer.addItem(swModuleID);
final Item item = swcontactContainer.addItem(swModuleID);
item.getItemProperty("SWModuleId").setValue(swModuleID.toString());
item.getItemProperty(SW_MODULE_NAME_MSG)
.setValue(manageDistUIState.getDeleteSofwareModulesList().get(swModuleID));
@@ -640,7 +641,8 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
contactContainer.addContainerProperty(DIST_ID_NAME, DistributionSetIdName.class, "");
contactContainer.addContainerProperty(SOFTWARE_MODULE_ID_NAME, SoftwareModuleIdName.class, "");
final Map<DistributionSetIdName, Set<SoftwareModuleIdName>> assignedList = manageDistUIState.getAssignedList();
final Map<DistributionSetIdName, HashSet<SoftwareModuleIdName>> assignedList = manageDistUIState
.getAssignedList();
assignedList.forEach((distIdname, softIdNameSet) -> softIdNameSet.forEach(softIdName -> {
final String itemId = HawkbitCommonUtil.concatStrings("|||", distIdname.getId().toString(),
@@ -672,8 +674,8 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
});
int count = 0;
for (final Entry<DistributionSetIdName, Set<SoftwareModuleIdName>> entry : manageDistUIState.getAssignedList()
.entrySet()) {
for (final Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> entry : manageDistUIState
.getAssignedList().entrySet()) {
count += entry.getValue().size();
}
addToConsolitatedMsg(FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE
@@ -707,7 +709,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
if (softIdNameSet.isEmpty()) {
manageDistUIState.getAssignedList().remove(discardDistIdName);
}
final Map<Long, Set<SoftwareModuleIdName>> map = manageDistUIState.getConsolidatedDistSoftwarewList()
final Map<Long, HashSet<SoftwareModuleIdName>> map = manageDistUIState.getConsolidatedDistSoftwarewList()
.get(discardDistIdName);
map.keySet().forEach(typeId -> map.get(typeId).remove(discardSoftIdName));

View File

@@ -40,11 +40,11 @@ public class ManageDistUIState implements Serializable {
@Autowired
private ManageSoftwareModuleFilters softwareModuleFilters;
private final Map<DistributionSetIdName, Set<SoftwareModuleIdName>> assignedList = new HashMap<DistributionSetIdName, Set<SoftwareModuleIdName>>();
private final Map<DistributionSetIdName, HashSet<SoftwareModuleIdName>> assignedList = new HashMap<>();
private final Set<DistributionSetIdName> deletedDistributionList = new HashSet<DistributionSetIdName>();
private final Set<DistributionSetIdName> deletedDistributionList = new HashSet<>();
private Set<DistributionSetIdName> selectedDistributions = new HashSet<DistributionSetIdName>();
private Set<DistributionSetIdName> selectedDistributions = new HashSet<>();
private DistributionSetIdName lastSelectedDistribution;
@@ -66,9 +66,9 @@ public class ManageDistUIState implements Serializable {
private boolean isDsTableMaximized = Boolean.FALSE;
private final Map<String, SoftwareModuleIdName> assignedSoftwareModuleDetails = new HashMap<String, SoftwareModuleIdName>();
private final Map<String, SoftwareModuleIdName> assignedSoftwareModuleDetails = new HashMap<>();
private final Map<DistributionSetIdName, Map<Long, Set<SoftwareModuleIdName>>> consolidatedDistSoftwarewList = new HashMap<DistributionSetIdName, Map<Long, Set<SoftwareModuleIdName>>>();
private final Map<DistributionSetIdName, HashMap<Long, HashSet<SoftwareModuleIdName>>> consolidatedDistSoftwarewList = new HashMap<>();
private boolean noDataAvilableSwModule = Boolean.FALSE;
@@ -89,10 +89,11 @@ public class ManageDistUIState implements Serializable {
}
/**
*
* Need HashSet because the Set have to be serializable
*
* @return the assignedList
*/
public Map<DistributionSetIdName, Set<SoftwareModuleIdName>> getAssignedList() {
public Map<DistributionSetIdName, HashSet<SoftwareModuleIdName>> getAssignedList() {
return assignedList;
}
@@ -119,7 +120,7 @@ public class ManageDistUIState implements Serializable {
}
public void setSelectedDistributions(final Set<DistributionSetIdName> slectedDistributions) {
this.selectedDistributions = slectedDistributions;
selectedDistributions = slectedDistributions;
}
/**
@@ -140,7 +141,7 @@ public class ManageDistUIState implements Serializable {
* @return the selectedBaseSwModuleId
*/
public Optional<Long> getSelectedBaseSwModuleId() {
return this.selectedBaseSwModuleId != null ? Optional.of(this.selectedBaseSwModuleId) : Optional.empty();
return selectedBaseSwModuleId != null ? Optional.of(selectedBaseSwModuleId) : Optional.empty();
}
/**
@@ -214,7 +215,7 @@ public class ManageDistUIState implements Serializable {
/**
* Get isSwModuleTableMaximized.
*
*
* @return boolean
*/
public boolean isDsTableMaximized() {
@@ -223,11 +224,11 @@ public class ManageDistUIState implements Serializable {
/***
* Set isDsModuleTableMaximized.
*
*
* @param isDsModuleTableMaximized
*/
public void setDsTableMaximized(final boolean isDsModuleTableMaximized) {
this.isDsTableMaximized = isDsModuleTableMaximized;
isDsTableMaximized = isDsModuleTableMaximized;
}
public Map<String, SoftwareModuleIdName> getAssignedSoftwareModuleDetails() {
@@ -279,7 +280,12 @@ public class ManageDistUIState implements Serializable {
this.noDataAvailableDist = noDataAvailableDist;
}
public Map<DistributionSetIdName, Map<Long, Set<SoftwareModuleIdName>>> getConsolidatedDistSoftwarewList() {
/**
* Need HashSet because the Set have to be serializable
*
* @return map
*/
public Map<DistributionSetIdName, HashMap<Long, HashSet<SoftwareModuleIdName>>> getConsolidatedDistSoftwarewList() {
return consolidatedDistSoftwarewList;
}

View File

@@ -8,6 +8,10 @@
*/
package org.eclipse.hawkbit.ui.filtermanagement;
import java.awt.event.FocusListener;
import java.util.concurrent.Executor;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -26,6 +30,7 @@ import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
@@ -37,10 +42,12 @@ import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
@@ -49,6 +56,7 @@ import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
@@ -80,6 +88,10 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
@Autowired
private UINotification notification;
@Autowired
@Qualifier("uiExecutor")
private transient Executor executor;
private Label headerCaption;
private TextField queryTextField;
@@ -110,6 +122,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private LayoutClickListener nameLayoutClickListner;
private boolean validationFailed = false;
/**
* Initialize the Campaign Status History Header.
*/
@@ -123,9 +137,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
eventBus.subscribe(this);
}
/**
*
*/
private void restoreOnLoad() {
if (filterManagementUIState.isEditViewDisplayed()) {
populateComponents();
@@ -138,17 +149,20 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final CustomFilterUIEvent custFUIEvent) {
if (custFUIEvent == CustomFilterUIEvent.TARGET_FILTER_DETAIL_VIEW) {
populateComponents();
eventBus.publish(this, CustomFilterUIEvent.TARGET_DETAILS_VIEW);
} else if (custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
setUpCaptionLayout(true);
resetComponents();
}
void onEvent(final CustomFilterUIEvent custFUIEvent) {
if (custFUIEvent == CustomFilterUIEvent.TARGET_FILTER_DETAIL_VIEW) {
populateComponents();
eventBus.publish(this, CustomFilterUIEvent.TARGET_DETAILS_VIEW);
} else if (custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
setUpCaptionLayout(true);
resetComponents();
} else if (custFUIEvent == CustomFilterUIEvent.TARGET_FILTER_STATUS_HIDE) {
this.getUI().access(() -> updateStatusIconAfterTablePopulated());
}
}
}
private void populateComponents() {
if (filterManagementUIState.getTfQuery().isPresent()) {
queryTextField.setValue(filterManagementUIState.getTfQuery().get().getQuery());
@@ -156,7 +170,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
oldFilterName = filterManagementUIState.getTfQuery().get().getName();
oldFilterQuery = filterManagementUIState.getTfQuery().get().getQuery();
}
searchLayout.addComponentAsFirst(validationIcon);
showValidationSuccesIcon();
titleFilterIconsLayout.addStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
headerCaption.setVisible(false);
@@ -167,18 +180,26 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
headerCaption.setVisible(true);
nameLabel.setValue("");
queryTextField.setValue("");
removeStatusIcon();
setInitialStatusIconStyle(validationIcon);
validationFailed = false;
saveButton.setEnabled(false);
titleFilterIconsLayout.removeStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
}
private Label createStatusIcon() {
final Label statusIcon = new Label(FontAwesome.CHECK_CIRCLE.getHtml(), ContentMode.HTML);
statusIcon.addStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
statusIcon.setSizeUndefined();
final Label statusIcon = new Label();
statusIcon.setImmediate(true);
statusIcon.setContentMode(ContentMode.HTML);
statusIcon.setSizeFull();
setInitialStatusIconStyle(statusIcon);
return statusIcon;
}
private void setInitialStatusIconStyle(final Label statusIcon) {
statusIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
statusIcon.setStyleName("hide-status-label");
}
private void createComponents() {
headerCaption = SPUIComponentProvider.getLabel(SPUILabelDefinitions.VAR_CREATE_FILTER,
SPUILabelDefinitions.SP_WIDGET_CAPTION);
@@ -199,10 +220,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
closeIcon = createSearchResetIcon();
}
/**
* @return
*/
private TextField createNameTextField() {
final TextField nameField = SPUIComponentProvider.getTextField("", ValoTheme.TEXTFIELD_TINY, false, null,
i18n.get("textfield.customfiltername"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
@@ -238,10 +257,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
};
}
/**
* @param event
* @return
*/
private void onFiterNameChange(final TextChangeEvent event) {
if (isNameAndQueryEmpty(event.getText(), queryTextField.getValue())
|| (event.getText().equals(oldFilterName) && queryTextField.getValue().equals(oldFilterQuery))) {
@@ -274,8 +289,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
searchLayout = new HorizontalLayout();
searchLayout.setSizeUndefined();
searchLayout.setSpacing(false);
searchLayout.addComponent(queryTextField);
searchLayout.addComponents(validationIcon, queryTextField);
searchLayout.addStyleName("custom-search-layout");
searchLayout.setComponentAlignment(validationIcon, Alignment.MIDDLE_CENTER);
final HorizontalLayout iconLayout = new HorizontalLayout();
iconLayout.setSizeUndefined();
@@ -308,25 +324,34 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private void addSearchLisenter() {
queryTextField.addTextChangeListener(new TextChangeListener() {
private static final long serialVersionUID = -6668604418942689391L;
@Override
public void textChange(final TextChangeEvent event) {
validationIcon.addStyleName("show-status-label");
showValidationInProgress();
onQueryChange(event.getText());
eventBus.publish(this, CustomFilterUIEvent.FILTER_TARGET_BY_QUERY);
executor.execute(new StatusCircledAsync());
}
});
}
class StatusCircledAsync implements Runnable {
@Override
public void run() {
eventBus.publish(this, CustomFilterUIEvent.FILTER_TARGET_BY_QUERY);
}
}
private void onQueryChange(final String text) {
boolean validationFailed = false;
if (!Strings.isNullOrEmpty(text)) {
final String input = text.toLowerCase();
searchLayout.addComponentAsFirst(validationIcon);
final ValidationResult validationResult = FilterQueryValidation.getExpectedTokens(input);
if (!validationResult.getIsValidationFailed()) {
showValidationSuccesIcon();
filterManagementUIState.setFilterQueryValue(input);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.FALSE);
validationFailed = false;
} else {
validationFailed = true;
filterManagementUIState.setFilterQueryValue(null);
@@ -336,15 +361,17 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
enableDisableSaveButton(validationFailed, input);
} else {
removeStatusIcon();
setInitialStatusIconStyle(validationIcon);
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.TRUE);
}
queryTextField.setValue(text);
}
private void enableDisableSaveButton(final boolean validationFailed, final String query) {
if (validationFailed || (isNameAndQueryEmpty(nameTextField.getValue(), query)
|| (query.equals(oldFilterQuery) && nameTextField.getValue().equals(oldFilterName)))) {
if (validationFailed
|| (isNameAndQueryEmpty(nameTextField.getValue(), query) || (query.equals(oldFilterQuery) && nameTextField
.getValue().equals(oldFilterName)))) {
saveButton.setEnabled(false);
} else {
if (hasSavePermission()) {
@@ -360,16 +387,10 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return false;
}
private void removeStatusIcon() {
if (searchLayout.getComponentIndex(validationIcon) != -1) {
searchLayout.removeComponent(validationIcon);
}
}
private void showValidationSuccesIcon() {
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
validationIcon.setDescription("");
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
}
private void showValidationFailureIcon() {
@@ -377,6 +398,11 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
validationIcon.setStyleName(SPUIStyleDefinitions.ERROR_ICON);
}
private void showValidationInProgress() {
validationIcon.setValue(null);
validationIcon.setStyleName(SPUIStyleDefinitions.TARGET_FILTER_SEARCH_PROGRESS_INDICATOR_STYLE);
}
private SPUIButton createSearchResetIcon() {
final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton("create.custom.filter.close.Id", "", "",
null, false, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
@@ -392,6 +418,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
textField.setWidth(900.0F, Unit.PIXELS);
textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
textField.setTextChangeTimeout(1000);
textField.addShortcutListener(new AbstractField.FocusShortcut(textField, KeyCode.ENTER));
return textField;
}
@@ -443,8 +471,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
targetFilterQuery.setName(nameTextField.getValue());
targetFilterQuery.setQuery(queryTextField.getValue());
targetFilterQueryManagement.createTargetFilterQuery(targetFilterQuery);
notification.displaySuccess(
i18n.get("message.create.filter.success", new Object[] { targetFilterQuery.getName() }));
notification.displaySuccess(i18n.get("message.create.filter.success",
new Object[] { targetFilterQuery.getName() }));
eventBus.publish(this, CustomFilterUIEvent.CREATE_TARGET_FILTER_QUERY);
}
@@ -469,9 +497,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
}
/**
* @return
*/
private boolean doesAlreadyExists() {
if (targetFilterQueryManagement.findTargetFilterQueryByName(nameTextField.getValue()) != null) {
notification.displayValidationError(i18n.get("message.target.filter.duplicate", nameTextField.getValue()));
@@ -480,9 +505,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return false;
}
/**
* @return
*/
private boolean manadatoryFieldsPresent() {
if (Strings.isNullOrEmpty(nameTextField.getValue())
|| Strings.isNullOrEmpty(filterManagementUIState.getFilterQueryValue())) {
@@ -491,5 +513,12 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
return true;
}
private void updateStatusIconAfterTablePopulated() {
queryTextField.focus();
if (!validationFailed && !Strings.isNullOrEmpty(queryTextField.getValue())) {
showValidationSuccesIcon();
}
}
}

View File

@@ -37,12 +37,15 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.vaadin.data.Item;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
/**
*
@@ -72,13 +75,18 @@ public class CreateOrUpdateFilterTable extends Table {
*/
@PostConstruct
public void init() {
setStyleName("sp-table");
setSizeFull();
setImmediate(true);
setHeight(100.0f, Unit.PERCENTAGE);
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
addStyleName(ValoTheme.TABLE_SMALL);
setColumnCollapsingAllowed(true);
addCustomGeneratedColumns();
restoreOnLoad();
populateTableData();
setStyleName("sp-table");
setId(SPUIComponetIdProvider.CUSTOM_FILTER_TARGET_TABLE_ID);
setSelectable(false);
eventBus.subscribe(this);
}
@@ -89,19 +97,22 @@ public class CreateOrUpdateFilterTable extends Table {
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final CustomFilterUIEvent custFUIEvent) {
if (custFUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY
|| custFUIEvent == CustomFilterUIEvent.TARGET_DETAILS_VIEW
if (custFUIEvent == CustomFilterUIEvent.TARGET_DETAILS_VIEW
|| custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
populateTableData();
UI.getCurrent().access(() -> populateTableData());
} else if (custFUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
this.getUI().access(() -> onQuery());
}
}
private void restoreOnLoad() {
private void restoreOnLoad() {
if (filterManagementUIState.isCreateFilterViewDisplayed()) {
filterManagementUIState.setFilterQueryValue(null);
} else {
filterManagementUIState.getTfQuery()
.ifPresent(value -> filterManagementUIState.setFilterQueryValue(value.getQuery()));
filterManagementUIState.getTfQuery().ifPresent(
value -> filterManagementUIState.setFilterQueryValue(value.getQuery()));
}
}
@@ -117,9 +128,8 @@ public class CreateOrUpdateFilterTable extends Table {
targetQF.setQueryConfiguration(queryConfig);
// create lazy query container with lazy defination and query
final LazyQueryContainer targetTableContainer = new LazyQueryContainer(
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_CONT_ID_NAME),
targetQF);
final LazyQueryContainer targetTableContainer = new LazyQueryContainer(new LazyQueryDefinition(true,
SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_CONT_ID_NAME), targetQF);
targetTableContainer.getQueryView().getQueryDefinition().setMaxNestedPropertyDepth(PROPERTY_DEPT);
return targetTableContainer;
@@ -149,9 +159,6 @@ public class CreateOrUpdateFilterTable extends Table {
setCollapsibleColumns();
}
/**
*
*/
private void setCollapsibleColumns() {
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, true);
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, true);
@@ -175,16 +182,16 @@ public class CreateOrUpdateFilterTable extends Table {
private List<TableColumn> getVisbleColumns() {
final List<TableColumn> columnList = new ArrayList<>();
columnList.add(new TableColumn(SPUILabelDefinitions.NAME, i18n.get("header.name"), 0.15F));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_BY, i18n.get("header.createdBy"), 0.1F));
columnList.add(new TableColumn(SPUILabelDefinitions.NAME, i18n.get("header.name"),0.15f));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_BY, i18n.get("header.createdBy"), 0.1f));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_DATE, i18n.get("header.createdDate"), 0.1F));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, i18n.get("header.modifiedBy"), 0.1F));
columnList.add(
new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F));
columnList.add(new TableColumn(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER,
i18n.get("header.assigned.ds"), 0.125F));
columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER,
i18n.get("header.installed.ds"), 0.125F));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"),
0.1F));
columnList.add(new TableColumn(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER, i18n
.get("header.assigned.ds"), 0.125F));
columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, i18n
.get("header.installed.ds"), 0.125F));
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.1F));
columnList.add(new TableColumn(SPUILabelDefinitions.STATUS_ICON, i18n.get("header.status"), 0.1F));
return columnList;
@@ -192,8 +199,8 @@ public class CreateOrUpdateFilterTable extends Table {
private Component getStatusIcon(final Object itemId) {
final Item row1 = getItem(itemId);
final TargetUpdateStatus targetStatus = (TargetUpdateStatus) row1
.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).getValue();
final TargetUpdateStatus targetStatus = (TargetUpdateStatus) row1.getItemProperty(
SPUILabelDefinitions.VAR_TARGET_STATUS).getValue();
final Label label = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE);
label.setContentMode(ContentMode.HTML);
if (targetStatus == TargetUpdateStatus.PENDING) {
@@ -234,5 +241,9 @@ public class CreateOrUpdateFilterTable extends Table {
protected void addCustomGeneratedColumns() {
addGeneratedColumn(SPUILabelDefinitions.STATUS_ICON, (source, itemId, columnId) -> getStatusIcon(itemId));
}
private void onQuery() {
populateTableData();
eventBus.publish(this, CustomFilterUIEvent.TARGET_FILTER_STATUS_HIDE);
}
}

View File

@@ -126,11 +126,14 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
prxyTarget.setInstalledDistributionSet(installedDistributionSet);
final DistributionSet assignedDistributionSet = target.getAssignedDistributionSet();
prxyTarget.setAssignedDistributionSet(assignedDistributionSet);
if (null != assignedDistributionSet) {
prxyTarget.setAssignedDistNameVersion(assignedDistributionSet.getName());
prxyTarget.setAssignedDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion(
assignedDistributionSet.getName(), assignedDistributionSet.getVersion()));
}
if (null != installedDistributionSet) {
prxyTarget.setInstalledDistNameVersion(installedDistributionSet.getName());
prxyTarget.setInstalledDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion(
installedDistributionSet.getName(), installedDistributionSet.getVersion()));
}
prxyTarget.setUpdateStatus(targ.getTargetInfo().getUpdateStatus());
prxyTarget.setLastTargetQuery(targ.getTargetInfo().getLastTargetQuery());

View File

@@ -12,6 +12,7 @@ import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.ui.HawkbitUI;
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.footer.TargetFilterCountMessageLabel;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
@@ -23,6 +24,7 @@ import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
@@ -55,6 +57,9 @@ public class FilterManagementView extends VerticalLayout implements View {
@Autowired
private FilterManagementUIState filterManagementUIState;
@Autowired
private TargetFilterCountMessageLabel targetFilterCountMessageLabel;
@Autowired
private transient EventBus.SessionEventBus eventBus;
@@ -75,7 +80,6 @@ public class FilterManagementView extends VerticalLayout implements View {
setSizeFull();
setSpacing(false);
setMargin(false);
addStyleName("table-layout");
if (filterManagementUIState.isCreateFilterViewDisplayed()) {
viewCreateTargetFilterLayout();
} else if (filterManagementUIState.isEditViewDisplayed()) {
@@ -89,8 +93,9 @@ public class FilterManagementView extends VerticalLayout implements View {
void onEvent(final CustomFilterUIEvent custFilterUIEvent) {
if (custFilterUIEvent == CustomFilterUIEvent.TARGET_FILTER_DETAIL_VIEW) {
viewTargetFilterDetailLayout();
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
UI.getCurrent().access(() -> viewCreateTargetFilterLayout());
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK
|| custFilterUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
this.getUI().access(() -> viewCreateTargetFilterLayout());
} else if (custFilterUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW) {
UI.getCurrent().access(() -> viewListView());
}
@@ -107,18 +112,47 @@ public class FilterManagementView extends VerticalLayout implements View {
private void buildFilterDetailOrCreateView() {
removeAllComponents();
addComponents(createNewFilterHeader, createNewFilterTable);
setComponentAlignment(createNewFilterHeader, Alignment.TOP_LEFT);
setComponentAlignment(createNewFilterTable, Alignment.TOP_LEFT);
setExpandRatio(createNewFilterTable, 1.0f);
final VerticalLayout tableHeaderLayout = new VerticalLayout();
tableHeaderLayout.setSizeFull();
tableHeaderLayout.setSpacing(false);
tableHeaderLayout.setMargin(false);
tableHeaderLayout.setStyleName("table-layout");
tableHeaderLayout.addComponent(createNewFilterHeader);
tableHeaderLayout.setComponentAlignment(createNewFilterHeader, Alignment.TOP_CENTER);
tableHeaderLayout.addComponent(createNewFilterTable);
tableHeaderLayout.setComponentAlignment(createNewFilterTable, Alignment.TOP_CENTER);
tableHeaderLayout.setExpandRatio(createNewFilterTable, 1.0f);
addComponent(tableHeaderLayout);
setComponentAlignment(tableHeaderLayout, Alignment.TOP_CENTER);
setExpandRatio(tableHeaderLayout, 1.0f);
final HorizontalLayout targetsCountmessageLabelLayout = addTargetFilterMessageLabel();
addComponent(targetsCountmessageLabelLayout);
setComponentAlignment(targetsCountmessageLabelLayout, Alignment.BOTTOM_CENTER);
}
private void viewListView() {
removeAllComponents();
addComponents(targetFilterHeader, targetFilterTable);
setComponentAlignment(targetFilterHeader, Alignment.TOP_LEFT);
setComponentAlignment(targetFilterTable, Alignment.TOP_LEFT);
setExpandRatio(targetFilterTable, 1.0f);
final VerticalLayout tableHeaderLayout = new VerticalLayout();
tableHeaderLayout.setSizeFull();
tableHeaderLayout.setSpacing(false);
tableHeaderLayout.setMargin(false);
tableHeaderLayout.setStyleName("table-layout");
tableHeaderLayout.addComponent(targetFilterHeader);
tableHeaderLayout.setComponentAlignment(targetFilterHeader, Alignment.TOP_CENTER);
tableHeaderLayout.addComponent(targetFilterTable);
tableHeaderLayout.setComponentAlignment(targetFilterTable, Alignment.TOP_CENTER);
tableHeaderLayout.setExpandRatio(targetFilterTable, 1.0f);
addComponent(tableHeaderLayout);
}
private HorizontalLayout addTargetFilterMessageLabel() {
final HorizontalLayout messageLabelLayout = new HorizontalLayout();
messageLabelLayout.addComponent(targetFilterCountMessageLabel);
messageLabelLayout.addStyleName("footer-layout");
return messageLabelLayout;
}
}

View File

@@ -41,6 +41,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
@@ -83,18 +84,20 @@ public class TargetFilterTable extends Table {
* Initialize the Action History Table.
*/
@PostConstruct
public void init() {
addCustomGeneratedColumns();
populateTableData();
setStyleName("sp-table");
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
addStyleName(ValoTheme.TABLE_SMALL);
setColumnCollapsingAllowed(true);
setColumnProperties();
setId(SPUIComponetIdProvider.TAEGET_FILTER_TABLE_ID);
eventBus.subscribe(this);
setSizeFull();
}
public void init() {
setStyleName("sp-table");
setSizeFull();
setImmediate(true);
setHeight(100.0f, Unit.PERCENTAGE);
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
addStyleName(ValoTheme.TABLE_SMALL);
addCustomGeneratedColumns();
populateTableData();
setColumnCollapsingAllowed(true);
setColumnProperties();
setId(SPUIComponetIdProvider.TAEGET_FILTER_TABLE_ID);
eventBus.subscribe(this);
}
@PreDestroy
void destroy() {
@@ -103,14 +106,12 @@ public class TargetFilterTable extends Table {
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final CustomFilterUIEvent filterEvent) {
UI.getCurrent().access(() -> {
if (filterEvent == CustomFilterUIEvent.FILTER_BY_CUST_FILTER_TEXT
|| filterEvent == CustomFilterUIEvent.FILTER_BY_CUST_FILTER_TEXT_REMOVE
|| filterEvent == CustomFilterUIEvent.CREATE_TARGET_FILTER_QUERY
|| filterEvent == CustomFilterUIEvent.UPDATED_TARGET_FILTER_QUERY) {
refreshContainer();
}
});
if (filterEvent == CustomFilterUIEvent.FILTER_BY_CUST_FILTER_TEXT
|| filterEvent == CustomFilterUIEvent.FILTER_BY_CUST_FILTER_TEXT_REMOVE
|| filterEvent == CustomFilterUIEvent.CREATE_TARGET_FILTER_QUERY
|| filterEvent == CustomFilterUIEvent.UPDATED_TARGET_FILTER_QUERY) {
UI.getCurrent().access(() -> refreshContainer());
}
}
/**
@@ -125,8 +126,8 @@ public class TargetFilterTable extends Table {
targetQF.setQueryConfiguration(queryConfig);
// create lazy query container with lazy defination and query
final LazyQueryContainer targetFilterContainer = new LazyQueryContainer(
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_ID), targetQF);
final LazyQueryContainer targetFilterContainer = new LazyQueryContainer(new LazyQueryDefinition(true,
SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_ID), targetQF);
targetFilterContainer.getQueryView().getQueryDefinition().setMaxNestedPropertyDepth(PROPERTY_DEPT);
return targetFilterContainer;
@@ -135,8 +136,8 @@ public class TargetFilterTable extends Table {
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<String, Object>();
filterManagementUIState.getCustomFilterSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
filterManagementUIState.getCustomFilterSearchText().ifPresent(
value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
return queryConfig;
}
@@ -205,8 +206,8 @@ public class TargetFilterTable extends Table {
* of the deleted custom filter.
*/
notification.displaySuccess(
i18n.get("message.delete.filter.success", new Object[] { deletedFilterName }));
notification.displaySuccess(i18n.get("message.delete.filter.success",
new Object[] { deletedFilterName }));
refreshContainer();
}
});

View File

@@ -15,5 +15,5 @@ package org.eclipse.hawkbit.ui.filtermanagement.event;
*
*/
public enum CustomFilterUIEvent {
FILTER_TARGET_BY_QUERY, FILTER_BY_CUST_FILTER_TEXT, FILTER_BY_CUST_FILTER_TEXT_REMOVE, CREATE_NEW_FILTER_CLICK, EXIT_CREATE_OR_UPDATE_FILTRER_VIEW, TARGET_FILTER_DETAIL_VIEW, TARGET_DETAILS_VIEW, CREATE_TARGET_FILTER_QUERY, UPDATED_TARGET_FILTER_QUERY,
FILTER_TARGET_BY_QUERY, FILTER_BY_CUST_FILTER_TEXT, FILTER_BY_CUST_FILTER_TEXT_REMOVE, CREATE_NEW_FILTER_CLICK, EXIT_CREATE_OR_UPDATE_FILTRER_VIEW, TARGET_FILTER_DETAIL_VIEW, TARGET_DETAILS_VIEW, CREATE_TARGET_FILTER_QUERY, UPDATED_TARGET_FILTER_QUERY, TARGET_FILTER_STATUS_HIDE
}

View File

@@ -0,0 +1,121 @@
/**
* 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.footer;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
/**
* @author Venugopal Boodidadinne(RBEI/BSJ)
*
* Count message label which display current filter details and details
* on pinning.
*/
@SpringComponent
@ViewScope
public class TargetFilterCountMessageLabel extends Label {
private static final long serialVersionUID = -7188528790042766877L;
@Autowired
private FilterManagementUIState filterManagementUIState;
@Autowired
private transient TargetManagement targetManagement;
@Autowired
private I18N i18n;
@Autowired
private transient EventBus.SessionEventBus eventBus;
/**
* PostConstruct method called by spring after bean has been initialized.
*/
@PostConstruct
public void postConstruct() {
applyStyle();
displayTargetFilterMessage();
eventBus.subscribe(this);
}
@PreDestroy
void destroy() {
eventBus.unsubscribe(this);
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final CustomFilterUIEvent custFUIEvent) {
if (custFUIEvent == CustomFilterUIEvent.TARGET_DETAILS_VIEW
|| custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK
|| custFUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW
|| custFUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
UI.getCurrent().access(() -> displayTargetFilterMessage());
}
}
private void applyStyle() {
addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE);
setContentMode(ContentMode.HTML);
setId(SPUIComponetIdProvider.COUNT_LABEL);
}
private void displayTargetFilterMessage() {
long totalTargets = 0;
if (filterManagementUIState.isCreateFilterViewDisplayed() || filterManagementUIState.isEditViewDisplayed()) {
if (null != filterManagementUIState.getFilterQueryValue()) {
totalTargets = targetManagement
.countTargetByTargetFilterQuery(filterManagementUIState.getFilterQueryValue());
}
final StringBuilder targetMessage = new StringBuilder(i18n.get("label.target.filtered.total"));
if (filterManagementUIState.getTargetsTruncated() != null) {
// set the icon
setIcon(FontAwesome.INFO_CIRCLE);
setDescription(i18n.get("label.target.filter.truncated", filterManagementUIState.getTargetsTruncated(),
SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES));
} else {
setIcon(null);
setDescription(null);
}
targetMessage.append(totalTargets);
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(i18n.get("label.filter.shown"));
if (totalTargets > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) {
targetMessage.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES);
} else {
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(totalTargets);
}
setCaption(targetMessage.toString());
}
}
}

View File

@@ -49,7 +49,7 @@ public class HawkbitLoginUI extends DefaultHawkbitUI {
private SpringViewProvider viewProvider;
@Autowired
private ApplicationContext context;
private transient ApplicationContext context;
@Override
protected void init(final VaadinRequest request) {

View File

@@ -79,10 +79,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
private I18N i18n;
@Autowired
private DeploymentManagement deploymentManagement;
private transient DeploymentManagement deploymentManagement;
@Autowired
private EventBus.SessionEventBus eventBus;
private transient EventBus.SessionEventBus eventBus;
@Autowired
private UINotification notification;
@@ -204,10 +204,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Get Action based on status.
*
*
* @param type
* as Action.Type
*
*
* @return List of Actions
*/
private List<Object> getVisbleColumns() {
@@ -227,12 +227,12 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* fetch the target details using controller id, and set it globally.
*
*
* @param selectedTarget
* reference of target
*/
public void populateTableData(final Target selectedTarget) {
this.target = selectedTarget;
target = selectedTarget;
refreshContainer();
}
@@ -255,7 +255,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Populate Container for Action.
*
*
* @param isActiveActions
* as flag
* @param reversedActions
@@ -275,14 +275,14 @@ public class ActionHistoryTable extends TreeTable implements Handler {
final Item item = hierarchicalContainer.addItem(actionWithStatusCount.getActionId());
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).setValue(
actionWithStatusCount.getActionStatus());
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN)
.setValue(actionWithStatusCount.getActionStatus());
/*
* add action id.
*/
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID).setValue(
actionWithStatusCount.getActionId().toString());
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID)
.setValue(actionWithStatusCount.getActionId().toString());
/*
* add active/inactive status to the item which will be used in
* Column generator to generate respective icon
@@ -294,28 +294,27 @@ public class ActionHistoryTable extends TreeTable implements Handler {
* add action Id to the item which will be used for fetching child
* items ( previous action status ) during expand
*/
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN).setValue(
actionWithStatusCount.getActionId());
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN)
.setValue(actionWithStatusCount.getActionId());
/*
* add distribution name to the item which will be displayed in the
* table. The name should not exceed certain limit.
*/
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(
HawkbitCommonUtil.getFormattedText(actionWithStatusCount.getDsName() + ":"
+ actionWithStatusCount.getDsVersion()));
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(HawkbitCommonUtil
.getFormattedText(actionWithStatusCount.getDsName() + ":" + actionWithStatusCount.getDsVersion()));
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).setValue(action);
/* Default no child */
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getActionId(), false);
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
.setValue(
SPDateTimeUtil.getFormattedDate((actionWithStatusCount.getActionLastModifiedAt() != null) ? actionWithStatusCount
.getActionLastModifiedAt() : actionWithStatusCount.getActionCreatedAt()));
.setValue(SPDateTimeUtil.getFormattedDate((actionWithStatusCount.getActionLastModifiedAt() != null)
? actionWithStatusCount.getActionLastModifiedAt()
: actionWithStatusCount.getActionCreatedAt()));
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME).setValue(
actionWithStatusCount.getRolloutName());
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME)
.setValue(actionWithStatusCount.getRolloutName());
if (actionWithStatusCount.getActionStatusCount() > 0) {
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getActionId(), true);
@@ -390,10 +389,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
}
final String distName = (String) hierarchicalContainer.getItem(itemId)
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).getValue();
final Label activeStatusIcon = createActiveStatusLabel(
activeValue,
final Label activeStatusIcon = createActiveStatusLabel(activeValue,
(Action.Status) hierarchicalContainer.getItem(itemId)
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue() == Action.Status.ERROR);
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN)
.getValue() == Action.Status.ERROR);
activeStatusIcon.setId(new StringJoiner(".").add(distName).add(itemId.toString())
.add(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE).add(activeValue).toString());
return activeStatusIcon;
@@ -412,7 +411,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Load the rows of previous status history of the selected action row and
* add it next to the selected action row.
*
*
* @param parentRowIdx
* index of the selected action row.
*/
@@ -447,14 +446,14 @@ public class ActionHistoryTable extends TreeTable implements Handler {
*/
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).setValue("");
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(
HawkbitCommonUtil.getFormattedText(action.getDistributionSet().getName() + ":"
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST)
.setValue(HawkbitCommonUtil.getFormattedText(action.getDistributionSet().getName() + ":"
+ action.getDistributionSet().getVersion()));
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME).setValue(
SPDateTimeUtil.getFormattedDate(actionStatus.getCreatedAt()));
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).setValue(
actionStatus.getStatus());
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
.setValue(SPDateTimeUtil.getFormattedDate(actionStatus.getCreatedAt()));
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN)
.setValue(actionStatus.getStatus());
showOrHideMessage(childItem, actionStatus);
/* No further child items allowed for the child items */
((Hierarchical) hierarchicalContainer).setChildrenAllowed(childId, false);
@@ -469,7 +468,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Hide the rows of previous status history of the selected action row.
*
*
* @param parentRowIdx
* index of the selected action row.
*/
@@ -487,7 +486,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Get status icon.
*
*
* @param status
* as Status
* @return Label as UI
@@ -561,13 +560,11 @@ public class ActionHistoryTable extends TreeTable implements Handler {
if (actionWithActiveStatus.isHitAutoForceTime(currentTimeMillis)) {
autoForceLabel.setDescription("autoforced");
autoForceLabel.setStyleName(STATUS_ICON_GREEN);
autoForceLabel.setDescription("auto forced since "
+ SPDateTimeUtil.getDurationFormattedString(actionWithActiveStatus.getForcedTime(),
currentTimeMillis, i18n));
autoForceLabel.setDescription("auto forced since " + SPDateTimeUtil
.getDurationFormattedString(actionWithActiveStatus.getForcedTime(), currentTimeMillis, i18n));
} else {
autoForceLabel.setDescription("auto forcing in "
+ SPDateTimeUtil.getDurationFormattedString(currentTimeMillis,
actionWithActiveStatus.getForcedTime(), i18n));
autoForceLabel.setDescription("auto forcing in " + SPDateTimeUtil
.getDurationFormattedString(currentTimeMillis, actionWithActiveStatus.getForcedTime(), i18n));
autoForceLabel.setStyleName("statusIconPending");
autoForceLabel.setValue(FontAwesome.HISTORY.getHtml());
}
@@ -576,7 +573,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Create Status Label.
*
*
* @param activeValue
* as String
* @return Labeal as UI
@@ -649,7 +646,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* create Message block for Actions.
*
*
* @param messages
* as List of msg
* @return Component as UI
@@ -748,7 +745,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Show confirmation window and if ok then only, force the action.
*
*
* @param actionId
* as Id if the action needs to be forced.
*/
@@ -776,9 +773,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
private void confirmAndForceQuitAction(final Long actionId) {
/* Display the confirmation */
final ConfirmationDialog confirmDialog = new ConfirmationDialog(
i18n.get("caption.forcequit.action.confirmbox"), i18n.get("message.forcequit.action.confirm"),
i18n.get("button.ok"), i18n.get("button.cancel"), ok -> {
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.forcequit.action.confirmbox"),
i18n.get("message.forcequit.action.confirm"), i18n.get("button.ok"), i18n.get("button.cancel"), ok -> {
if (ok) {
final boolean cancelResult = forceQuitActiveAction(actionId);
if (cancelResult) {
@@ -793,14 +789,14 @@ public class ActionHistoryTable extends TreeTable implements Handler {
notification.displayValidationError(i18n.get("message.forcequit.action.failed"));
}
}
}, FontAwesome.WARNING);
} , FontAwesome.WARNING);
UI.getCurrent().addWindow(confirmDialog.getWindow());
confirmDialog.getWindow().bringToFront();
}
/**
* Show confirmation window and if ok then only, cancel the action.
*
*
* @param actionId
* as Id if the action needs to be cancelled.
*/
@@ -880,8 +876,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
if (managementUIState.getDistributionTableFilters().getPinnedTargetId().isPresent()
&& null != managementUIState.getDistributionTableFilters().getPinnedTargetId().get()) {
final String alreadyPinnedControllerId = managementUIState.getDistributionTableFilters()
.getPinnedTargetId().get();
final String alreadyPinnedControllerId = managementUIState.getDistributionTableFilters().getPinnedTargetId()
.get();
// if the current target is pinned publish a pin event again
if (null != alreadyPinnedControllerId && alreadyPinnedControllerId.equals(target.getControllerId())) {
eventBus.publish(this, PinUnpinEvent.PIN_TARGET);
@@ -898,7 +894,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
/**
* Set messages false.
*
*
* @param alreadyHasMessages
* the alreadyHasMessages to set
*/

Some files were not shown because too many files have changed in this diff Show More