Added integration option with device simulator.
Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -27,6 +27,7 @@ public class TargetBuilder {
|
|||||||
private String controllerId;
|
private String controllerId;
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
|
private String address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
@@ -48,6 +49,16 @@ public class TargetBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param address
|
||||||
|
* the address of the target
|
||||||
|
* @return the builder itself
|
||||||
|
*/
|
||||||
|
public TargetBuilder address(final String address) {
|
||||||
|
this.address = address;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param description
|
* @param description
|
||||||
* the description of the target
|
* the description of the target
|
||||||
@@ -121,6 +132,7 @@ public class TargetBuilder {
|
|||||||
}
|
}
|
||||||
body.setName(name + suffix);
|
body.setName(name + suffix);
|
||||||
body.setDescription(description);
|
body.setDescription(description);
|
||||||
|
body.setAddress(address);
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,12 @@
|
|||||||
package org.eclipse.hawkbit.mgmt.client;
|
package org.eclipse.hawkbit.mgmt.client;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration;
|
import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration;
|
||||||
|
import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract;
|
||||||
|
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
|
||||||
import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario;
|
import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario;
|
||||||
import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample;
|
import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample;
|
||||||
|
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.FeignMultipartEncoder;
|
||||||
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
@@ -18,11 +22,19 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.cloud.netflix.feign.EnableFeignClients;
|
import org.springframework.cloud.netflix.feign.EnableFeignClients;
|
||||||
|
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import feign.Feign;
|
||||||
|
import feign.Logger;
|
||||||
import feign.auth.BasicAuthRequestInterceptor;
|
import feign.auth.BasicAuthRequestInterceptor;
|
||||||
|
import feign.jackson.JacksonDecoder;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableFeignClients
|
@EnableFeignClients
|
||||||
@@ -72,6 +84,21 @@ public class Application implements CommandLineRunner {
|
|||||||
return new CreateStartedRolloutExample();
|
return new CreateStartedRolloutExample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MgmtSoftwareModuleClientResource uploadSoftwareModule() {
|
||||||
|
final ObjectMapper mapper = new ObjectMapper()
|
||||||
|
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
|
.registerModule(new Jackson2HalModule());
|
||||||
|
|
||||||
|
return Feign.builder().contract(new IgnoreMultipleConsumersProducersSpringMvcContract())
|
||||||
|
.requestInterceptor(
|
||||||
|
new BasicAuthRequestInterceptor(configuration.getUsername(), configuration.getPassword()))
|
||||||
|
.logger(new Logger.ErrorLogger()).encoder(new FeignMultipartEncoder())
|
||||||
|
.decoder(new ResponseEntityDecoder(new JacksonDecoder(mapper)))
|
||||||
|
.target(MgmtSoftwareModuleClientResource.class,
|
||||||
|
configuration.getUrl() + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean containsArg(final String containsArg, final String... args) {
|
private boolean containsArg(final String containsArg, final String... args) {
|
||||||
for (final String arg : args) {
|
for (final String arg : args) {
|
||||||
if (arg.equalsIgnoreCase(containsArg)) {
|
if (arg.equalsIgnoreCase(containsArg)) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class ClientConfigurationProperties {
|
|||||||
private final List<Scenario> scenarios = new ArrayList<>();
|
private final List<Scenario> scenarios = new ArrayList<>();
|
||||||
|
|
||||||
public static class Scenario {
|
public static class Scenario {
|
||||||
|
private String tenant = "DEFAULT";
|
||||||
private int targets = 100;
|
private int targets = 100;
|
||||||
private int distributionSets = 10;
|
private int distributionSets = 10;
|
||||||
private int appModulesPerDistributionSet = 2;
|
private int appModulesPerDistributionSet = 2;
|
||||||
@@ -47,6 +48,46 @@ public class ClientConfigurationProperties {
|
|||||||
private String smSwName = "Application";
|
private String smSwName = "Application";
|
||||||
private String smFwName = "Firmware";
|
private String smFwName = "Firmware";
|
||||||
private String targetName = "Device";
|
private String targetName = "Device";
|
||||||
|
private int artifactsPerSM = 1;
|
||||||
|
private String targetAddress = "amqp:/simulator.replyTo";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Artifact size. Values can use the suffixed "MB" or "KB" to indicate a
|
||||||
|
* Megabyte or Kilobyte size.
|
||||||
|
*/
|
||||||
|
private String artifactSize = "1MB";
|
||||||
|
|
||||||
|
public String getTargetAddress() {
|
||||||
|
return targetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetAddress(final String targetAddress) {
|
||||||
|
this.targetAddress = targetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenant() {
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenant(final String tenant) {
|
||||||
|
this.tenant = tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getArtifactsPerSM() {
|
||||||
|
return artifactsPerSM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactsPerSM(final int artifactsPerSM) {
|
||||||
|
this.artifactsPerSM = artifactsPerSM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArtifactSize() {
|
||||||
|
return artifactSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactSize(final String artifactSize) {
|
||||||
|
this.artifactSize = artifactSize;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTargetName() {
|
public String getTargetName() {
|
||||||
return targetName;
|
return targetName;
|
||||||
|
|||||||
@@ -9,20 +9,25 @@
|
|||||||
package org.eclipse.hawkbit.mgmt.client.scenarios;
|
package org.eclipse.hawkbit.mgmt.client.scenarios;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties;
|
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties;
|
||||||
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario;
|
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource;
|
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
|
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
|
||||||
|
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSystemManagementClientResource;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource;
|
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder;
|
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder;
|
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.SoftwareModuleBuilder;
|
||||||
import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder;
|
import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder;
|
||||||
|
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -37,11 +42,19 @@ public class ConfigurableScenario {
|
|||||||
private MgmtDistributionSetClientResource distributionSetResource;
|
private MgmtDistributionSetClientResource distributionSetResource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("mgmtSoftwareModuleClientResource")
|
||||||
private MgmtSoftwareModuleClientResource softwareModuleResource;
|
private MgmtSoftwareModuleClientResource softwareModuleResource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("uploadSoftwareModule")
|
||||||
|
private MgmtSoftwareModuleClientResource uploadSoftwareModule;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MgmtTargetClientResource targetResource;
|
private MgmtTargetClientResource targetResource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MgmtSystemManagementClientResource systemManagementResource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ClientConfigurationProperties clientConfigurationProperties;
|
private ClientConfigurationProperties clientConfigurationProperties;
|
||||||
|
|
||||||
@@ -56,37 +69,76 @@ public class ConfigurableScenario {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createScenario(final Scenario scenario) {
|
private void createScenario(final Scenario scenario) {
|
||||||
|
systemManagementResource.deleteTenant(scenario.getTenant());
|
||||||
createTargets(scenario);
|
createTargets(scenario);
|
||||||
createDistributionSets(scenario);
|
createDistributionSets(scenario);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDistributionSets(final Scenario scenario) {
|
private void createDistributionSets(final Scenario scenario) {
|
||||||
|
final byte[] artifact = generateArtifact(scenario);
|
||||||
|
|
||||||
distributionSetResource
|
distributionSetResource
|
||||||
.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app")
|
.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app")
|
||||||
.version("1.0.").buildAsList(scenario.getDistributionSets()))
|
.version("1.0.").buildAsList(scenario.getDistributionSets()))
|
||||||
.getBody().parallelStream().forEach(dsSet -> {
|
.getBody().parallelStream().forEach(dsSet -> {
|
||||||
final List<MgmtSoftwareModule> modules = softwareModuleResource
|
final List<MgmtSoftwareModule> modules = addModules(scenario, dsSet, artifact);
|
||||||
.createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmFwName())
|
|
||||||
.version(dsSet.getVersion()).type("os").build())
|
|
||||||
.getBody();
|
|
||||||
modules.addAll(
|
|
||||||
softwareModuleResource
|
|
||||||
.createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmSwName())
|
|
||||||
.version(dsSet.getVersion() + ".").type("application")
|
|
||||||
.buildAsList(scenario.getAppModulesPerDistributionSet()))
|
|
||||||
.getBody());
|
|
||||||
|
|
||||||
final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder();
|
final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder();
|
||||||
modules.forEach(module -> assign.id(module.getModuleId()));
|
modules.forEach(module -> assign.id(module.getModuleId()));
|
||||||
|
|
||||||
distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build());
|
distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<MgmtSoftwareModule> addModules(final Scenario scenario, final MgmtDistributionSet dsSet,
|
||||||
|
final byte[] artifact) {
|
||||||
|
final List<MgmtSoftwareModule> modules = softwareModuleResource.createSoftwareModules(
|
||||||
|
new SoftwareModuleBuilder().name(scenario.getSmFwName()).version(dsSet.getVersion()).type("os").build())
|
||||||
|
.getBody();
|
||||||
|
modules.addAll(softwareModuleResource
|
||||||
|
.createSoftwareModules(
|
||||||
|
new SoftwareModuleBuilder().name(scenario.getSmSwName()).version(dsSet.getVersion() + ".")
|
||||||
|
.type("application").buildAsList(scenario.getAppModulesPerDistributionSet()))
|
||||||
|
.getBody());
|
||||||
|
|
||||||
|
for (int x = 0; x < scenario.getArtifactsPerSM(); x++) {
|
||||||
|
modules.forEach(module -> {
|
||||||
|
final ArtifactFile file = new ArtifactFile("dummyfile.dummy", null, "multipart/form-data", artifact);
|
||||||
|
uploadSoftwareModule.uploadArtifact(module.getModuleId(), file, null, null, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] generateArtifact(final Scenario scenario) {
|
||||||
|
// create random object
|
||||||
|
final Random random = new Random();
|
||||||
|
|
||||||
|
// create byte array
|
||||||
|
final byte[] nbyte = new byte[parseSize(scenario.getArtifactSize())];
|
||||||
|
|
||||||
|
// put the next byte in the array
|
||||||
|
random.nextBytes(nbyte);
|
||||||
|
|
||||||
|
return nbyte;
|
||||||
|
}
|
||||||
|
|
||||||
private void createTargets(final Scenario scenario) {
|
private void createTargets(final Scenario scenario) {
|
||||||
for (int i = 0; i < scenario.getTargets() / 100; i++) {
|
for (int i = 0; i < scenario.getTargets() / 100; i++) {
|
||||||
targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()).buildAsList(i * 100,
|
targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName())
|
||||||
(i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() : (i + 1) * 100));
|
.address(scenario.getTargetAddress()).buildAsList(i * 100,
|
||||||
|
(i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() - i * 100 : 100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int parseSize(final String s) {
|
||||||
|
final String size = s.toUpperCase();
|
||||||
|
if (size.endsWith("KB")) {
|
||||||
|
return Integer.valueOf(size.substring(0, size.length() - 2)) * 1024;
|
||||||
|
}
|
||||||
|
if (size.endsWith("MB")) {
|
||||||
|
return Integer.valueOf(size.substring(0, size.length() - 2)) * 1024 * 1024;
|
||||||
|
}
|
||||||
|
return Integer.valueOf(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody;
|
|||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example for creating and starting a Rollout.
|
* Example for creating and starting a Rollout.
|
||||||
@@ -45,6 +46,7 @@ public class CreateStartedRolloutExample {
|
|||||||
private MgmtDistributionSetClientResource distributionSetResource;
|
private MgmtDistributionSetClientResource distributionSetResource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("mgmtSoftwareModuleClientResource")
|
||||||
private MgmtSoftwareModuleClientResource softwareModuleResource;
|
private MgmtSoftwareModuleClientResource softwareModuleResource;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* 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.upload;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
public class ArtifactFile implements MultipartFile {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final String originalFilename;
|
||||||
|
|
||||||
|
private final String contentType;
|
||||||
|
|
||||||
|
private final byte[] content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ArtifactFile with the given content.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the file
|
||||||
|
* @param content
|
||||||
|
* the content of the file
|
||||||
|
*/
|
||||||
|
public ArtifactFile(final String name, final byte[] content) {
|
||||||
|
this(name, "", null, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ArtifactFile with the given content.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* of the file
|
||||||
|
* @param originalFilename
|
||||||
|
* the original filename (as on the client's machine)
|
||||||
|
* @param contentType
|
||||||
|
* the content type
|
||||||
|
* @param content
|
||||||
|
* of the file
|
||||||
|
*/
|
||||||
|
public ArtifactFile(final String name, final String originalFilename, final String contentType,
|
||||||
|
final byte[] content) {
|
||||||
|
Assert.hasLength(name, "Name must not be null");
|
||||||
|
this.name = name;
|
||||||
|
this.originalFilename = originalFilename != null ? originalFilename : "";
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.content = content != null ? content : new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOriginalFilename() {
|
||||||
|
return this.originalFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
return this.contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return this.content.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return this.content.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes() throws IOException {
|
||||||
|
return this.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new ByteArrayInputStream(this.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferTo(final File dest) throws IOException {
|
||||||
|
FileCopyUtils.copy(this.content, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.mgmt.client.scenarios.upload;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpOutputMessage;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import feign.RequestTemplate;
|
||||||
|
import feign.codec.EncodeException;
|
||||||
|
import feign.codec.Encoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A feign encoder implementation which handles {@link MultipartFile} body.
|
||||||
|
*/
|
||||||
|
public class FeignMultipartEncoder implements Encoder {
|
||||||
|
|
||||||
|
private final List<HttpMessageConverter<?>> converters = new RestTemplate().getMessageConverters();
|
||||||
|
private final HttpHeaders multipartHeaders = new HttpHeaders();
|
||||||
|
private final HttpHeaders jsonHeaders = new HttpHeaders();
|
||||||
|
|
||||||
|
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
public FeignMultipartEncoder() {
|
||||||
|
multipartHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||||
|
jsonHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(final Object object, final Type bodyType, final RequestTemplate template)
|
||||||
|
throws EncodeException {
|
||||||
|
|
||||||
|
encodeMultipartFormRequest(object, template);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeMultipartFormRequest(final Object value, final RequestTemplate template) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new EncodeException("Cannot encode request with null value.");
|
||||||
|
}
|
||||||
|
if (!isMultipartFile(value)) {
|
||||||
|
throw new EncodeException("Only multipart can be handled by this encoder");
|
||||||
|
}
|
||||||
|
encodeRequest(encodeMultipartFile((MultipartFile) value), multipartHeaders, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void encodeRequest(final Object value, final HttpHeaders requestHeaders, final RequestTemplate template)
|
||||||
|
throws EncodeException {
|
||||||
|
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
final HttpOutputMessage dummyRequest = new HttpOutputMessageImpl(outputStream, requestHeaders);
|
||||||
|
try {
|
||||||
|
final Class<?> requestType = value.getClass();
|
||||||
|
final MediaType requestContentType = requestHeaders.getContentType();
|
||||||
|
for (final HttpMessageConverter<?> messageConverter : converters) {
|
||||||
|
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||||
|
((HttpMessageConverter<Object>) messageConverter).write(value, requestContentType, dummyRequest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new EncodeException("Cannot encode request.", ex);
|
||||||
|
}
|
||||||
|
final HttpHeaders headers = dummyRequest.getHeaders();
|
||||||
|
if (headers != null) {
|
||||||
|
for (final Entry<String, List<String>> entry : headers.entrySet()) {
|
||||||
|
template.header(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* we should use a template output stream... this will cause issues if
|
||||||
|
* files are too big, since the whole request will be in memory.
|
||||||
|
*/
|
||||||
|
template.body(outputStream.toByteArray(), UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MultiValueMap<String, Object> encodeMultipartFile(final MultipartFile file) {
|
||||||
|
try {
|
||||||
|
final MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
|
||||||
|
multiValueMap.add("file", new MultipartFileResource(file.getName(), file.getSize(), file.getInputStream()));
|
||||||
|
return multiValueMap;
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new EncodeException("Cannot encode request.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMultipartFile(final Object object) {
|
||||||
|
return object instanceof MultipartFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HttpOutputMessageImpl implements HttpOutputMessage {
|
||||||
|
|
||||||
|
private final OutputStream body;
|
||||||
|
private final HttpHeaders headers;
|
||||||
|
|
||||||
|
public HttpOutputMessageImpl(final OutputStream body, final HttpHeaders headers) {
|
||||||
|
this.body = body;
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getBody() throws IOException {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy resource class. Wraps file content and its original name.
|
||||||
|
*/
|
||||||
|
static class MultipartFileResource extends InputStreamResource {
|
||||||
|
|
||||||
|
private final String filename;
|
||||||
|
private final long size;
|
||||||
|
|
||||||
|
public MultipartFileResource(final String filename, final long size, final InputStream inputStream) {
|
||||||
|
super(inputStream);
|
||||||
|
this.size = size;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilename() {
|
||||||
|
return this.filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException, IllegalStateException {
|
||||||
|
return super.getInputStream(); // To change body of generated
|
||||||
|
// methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long contentLength() throws IOException {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
hawkbit.url=localhost:8080
|
hawkbit.url=http://localhost:8080
|
||||||
hawkbit.username=admin
|
hawkbit.username=admin
|
||||||
hawkbit.password=admin
|
hawkbit.password=admin
|
||||||
|
|
||||||
@@ -21,3 +21,4 @@ spring.main.show-banner=false
|
|||||||
|
|
||||||
hawkbit.scenarios.[0].targets=10000
|
hawkbit.scenarios.[0].targets=10000
|
||||||
hawkbit.scenarios.[0].distribution-sets=100
|
hawkbit.scenarios.[0].distribution-sets=100
|
||||||
|
hawkbit.scenarios.[0].artifactsPerSM=0
|
||||||
@@ -18,6 +18,9 @@ public class MgmtTargetRequestBody {
|
|||||||
@JsonProperty(required = true)
|
@JsonProperty(required = true)
|
||||||
private String controllerId;
|
private String controllerId;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private String address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the name
|
* @return the name
|
||||||
*/
|
*/
|
||||||
@@ -66,4 +69,12 @@ public class MgmtTargetRequestBody {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(final String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ public final class MgmtTargetMapper {
|
|||||||
final Target target = entityFactory.generateTarget(targetRest.getControllerId());
|
final Target target = entityFactory.generateTarget(targetRest.getControllerId());
|
||||||
target.setDescription(targetRest.getDescription());
|
target.setDescription(targetRest.getDescription());
|
||||||
target.setName(targetRest.getName());
|
target.setName(targetRest.getName());
|
||||||
|
target.getTargetInfo().setAddress(targetRest.getAddress());
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
|||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||||
import org.eclipse.hawkbit.rest.exception.MessageNotReadableException;
|
import org.eclipse.hawkbit.rest.exception.MessageNotReadableException;
|
||||||
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
|
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
|
||||||
@@ -109,8 +109,8 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
actions.get(0).setStatus(Status.FINISHED);
|
actions.get(0).setStatus(Status.FINISHED);
|
||||||
controllerManagament.addUpdateActionStatus(entityFactory.generateActionStatus(actions.get(0),
|
controllerManagament.addUpdateActionStatus(entityFactory.generateActionStatus(actions.get(0), Status.FINISHED,
|
||||||
Status.FINISHED, System.currentTimeMillis(), "testmessage"));
|
System.currentTimeMillis(), "testmessage"));
|
||||||
|
|
||||||
final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionFields.ID.getFieldName());
|
final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionFields.ID.getFieldName());
|
||||||
final ActionStatus status = deploymentManagement
|
final ActionStatus status = deploymentManagement
|
||||||
@@ -682,6 +682,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
final Target test1 = entityFactory.generateTarget("id1");
|
final Target test1 = entityFactory.generateTarget("id1");
|
||||||
test1.setDescription("testid1");
|
test1.setDescription("testid1");
|
||||||
test1.setName("testname1");
|
test1.setName("testname1");
|
||||||
|
test1.getTargetInfo().setAddress("amqp://test123/foobar");
|
||||||
final Target test2 = entityFactory.generateTarget("id2");
|
final Target test2 = entityFactory.generateTarget("id2");
|
||||||
test2.setDescription("testid2");
|
test2.setDescription("testid2");
|
||||||
test2.setName("testname2");
|
test2.setName("testname2");
|
||||||
@@ -704,6 +705,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
.andExpect(jsonPath("[0].description", equalTo("testid1")))
|
.andExpect(jsonPath("[0].description", equalTo("testid1")))
|
||||||
.andExpect(jsonPath("[0].createdAt", not(equalTo(0))))
|
.andExpect(jsonPath("[0].createdAt", not(equalTo(0))))
|
||||||
.andExpect(jsonPath("[0].createdBy", equalTo("bumlux")))
|
.andExpect(jsonPath("[0].createdBy", equalTo("bumlux")))
|
||||||
|
.andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar")))
|
||||||
.andExpect(jsonPath("[1].name", equalTo("testname2")))
|
.andExpect(jsonPath("[1].name", equalTo("testname2")))
|
||||||
.andExpect(jsonPath("[1].createdBy", equalTo("bumlux")))
|
.andExpect(jsonPath("[1].createdBy", equalTo("bumlux")))
|
||||||
.andExpect(jsonPath("[1].controllerId", equalTo("id2")))
|
.andExpect(jsonPath("[1].controllerId", equalTo("id2")))
|
||||||
|
|||||||
@@ -179,25 +179,6 @@ public interface TargetManagement {
|
|||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
|
||||||
List<Target> createTargets(@NotNull Collection<Target> targets);
|
List<Target> createTargets(@NotNull Collection<Target> targets);
|
||||||
|
|
||||||
/**
|
|
||||||
* creating a new {@link Target} including poll status data. useful
|
|
||||||
* especially in plug and play scenarios.
|
|
||||||
*
|
|
||||||
* @param targets
|
|
||||||
* to be created *
|
|
||||||
* @param status
|
|
||||||
* of the target
|
|
||||||
* @param lastTargetQuery
|
|
||||||
* if a plug and play case
|
|
||||||
* @param address
|
|
||||||
* if a plug and play case
|
|
||||||
*
|
|
||||||
* @return newly created target
|
|
||||||
*/
|
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
|
|
||||||
List<Target> createTargets(@NotNull Collection<Target> targets, @NotNull TargetUpdateStatus status,
|
|
||||||
Long lastTargetQuery, URI address);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all targets with the given IDs.
|
* Deletes all targets with the given IDs.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,10 +16,19 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
public interface TargetInfo extends Serializable {
|
public interface TargetInfo extends Serializable {
|
||||||
/**
|
/**
|
||||||
* @return the address under whioch the target can be reached
|
* @return the address under which the target can be reached
|
||||||
*/
|
*/
|
||||||
URI getAddress();
|
URI getAddress();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param address
|
||||||
|
* the target address to set
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* If the given string violates RFC 2396
|
||||||
|
*/
|
||||||
|
void setAddress(String address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link Target} this info element belongs to.
|
* @return {@link Target} this info element belongs to.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -608,24 +608,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
}
|
}
|
||||||
final List<Target> savedTargets = new ArrayList<>();
|
final List<Target> savedTargets = new ArrayList<>();
|
||||||
for (final Target t : targets) {
|
for (final Target t : targets) {
|
||||||
final Target myTarget = createTarget(t);
|
final Target myTarget = createTarget(t, TargetUpdateStatus.UNKNOWN, null, t.getTargetInfo().getAddress());
|
||||||
savedTargets.add(myTarget);
|
|
||||||
}
|
|
||||||
return savedTargets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Modifying
|
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
|
||||||
public List<Target> createTargets(final Collection<Target> targets, final TargetUpdateStatus status,
|
|
||||||
final Long lastTargetQuery, final URI address) {
|
|
||||||
if (targetRepository.countByControllerIdIn(
|
|
||||||
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
|
|
||||||
throw new EntityAlreadyExistsException();
|
|
||||||
}
|
|
||||||
final List<Target> savedTargets = new ArrayList<>();
|
|
||||||
for (final Target t : targets) {
|
|
||||||
final Target myTarget = createTarget(t, status, lastTargetQuery, address);
|
|
||||||
savedTargets.add(myTarget);
|
savedTargets.add(myTarget);
|
||||||
}
|
}
|
||||||
return savedTargets;
|
return savedTargets;
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param address
|
* @param address
|
||||||
* the ipAddress to set
|
* the target address to set
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* If the given string violates RFC 2396
|
* If the given string violates RFC 2396
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ public abstract class JsonBuilder {
|
|||||||
try {
|
try {
|
||||||
builder.append(new JSONObject().put("name", module.getName())
|
builder.append(new JSONObject().put("name", module.getName())
|
||||||
.put("description", module.getDescription()).put("type", module.getType().getKey())
|
.put("description", module.getDescription()).put("type", module.getType().getKey())
|
||||||
.put("id", Long.MAX_VALUE).put("vendor", module.getVendor())
|
.put("id", Long.MAX_VALUE).put("vendor", module.getVendor()).put("version", module.getVersion())
|
||||||
.put("version", module.getVersion()).put("createdAt", "0").put("updatedAt", "0")
|
.put("createdAt", "0").put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh")
|
||||||
.put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh").toString());
|
.put("updatedBy", "fghdfkjghdfkjh").toString());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -185,15 +185,13 @@ public abstract class JsonBuilder {
|
|||||||
final List<String> messages = new ArrayList<String>();
|
final List<String> messages = new ArrayList<String>();
|
||||||
messages.add(message);
|
messages.add(message);
|
||||||
|
|
||||||
return new JSONObject()
|
return new JSONObject().put("id", id).put("time", "20140511T121314")
|
||||||
.put("id", id)
|
|
||||||
.put("time", "20140511T121314")
|
|
||||||
.put("status",
|
.put("status",
|
||||||
new JSONObject()
|
new JSONObject().put("execution", execution)
|
||||||
.put("execution", execution)
|
|
||||||
.put("result",
|
.put("result",
|
||||||
new JSONObject().put("finished", finished).put("progress",
|
new JSONObject().put("finished", finished).put("progress",
|
||||||
new JSONObject().put("cnt", 2).put("of", 5))).put("details", messages))
|
new JSONObject().put("cnt", 2).put("of", 5)))
|
||||||
|
.put("details", messages))
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -380,10 +378,13 @@ public abstract class JsonBuilder {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (final Target target : targets) {
|
for (final Target target : targets) {
|
||||||
try {
|
try {
|
||||||
|
final String address = target.getTargetInfo().getAddress() != null
|
||||||
|
? target.getTargetInfo().getAddress().toString() : null;
|
||||||
|
|
||||||
builder.append(new JSONObject().put("controllerId", target.getControllerId())
|
builder.append(new JSONObject().put("controllerId", target.getControllerId())
|
||||||
.put("description", target.getDescription()).put("name", target.getName())
|
.put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0")
|
||||||
.put("createdAt", "0").put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh")
|
.put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh")
|
||||||
.put("updatedBy", "fghdfkjghdfkjh").toString());
|
.put("address", address).toString());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -441,9 +442,7 @@ public abstract class JsonBuilder {
|
|||||||
throws JSONException {
|
throws JSONException {
|
||||||
final List<String> messages = new ArrayList<String>();
|
final List<String> messages = new ArrayList<String>();
|
||||||
messages.add(message);
|
messages.add(message);
|
||||||
return new JSONObject()
|
return new JSONObject().put("id", id).put("time", "20140511T121314")
|
||||||
.put("id", id)
|
|
||||||
.put("time", "20140511T121314")
|
|
||||||
.put("status",
|
.put("status",
|
||||||
new JSONObject().put("execution", execution)
|
new JSONObject().put("execution", execution)
|
||||||
.put("result", new JSONObject().put("finished", "success")).put("details", messages))
|
.put("result", new JSONObject().put("finished", "success")).put("details", messages))
|
||||||
@@ -453,13 +452,12 @@ public abstract class JsonBuilder {
|
|||||||
|
|
||||||
public static String configData(final String id, final Map<String, String> attributes, final String execution)
|
public static String configData(final String id, final Map<String, String> attributes, final String execution)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
return new JSONObject()
|
return new JSONObject().put("id", id).put("time", "20140511T121314")
|
||||||
.put("id", id)
|
|
||||||
.put("time", "20140511T121314")
|
|
||||||
.put("status",
|
.put("status",
|
||||||
new JSONObject().put("execution", execution)
|
new JSONObject().put("execution", execution)
|
||||||
.put("result", new JSONObject().put("finished", "success"))
|
.put("result", new JSONObject().put("finished", "success"))
|
||||||
.put("details", new ArrayList<String>())).put("data", attributes).toString();
|
.put("details", new ArrayList<String>()))
|
||||||
|
.put("data", attributes).toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user