diff --git a/examples/hawkbit-example-ddi-client/pom.xml b/examples/hawkbit-example-ddi-client/pom.xml index bd87a65bc..d2e9f7f72 100644 --- a/examples/hawkbit-example-ddi-client/pom.xml +++ b/examples/hawkbit-example-ddi-client/pom.xml @@ -1,17 +1,17 @@ - - 4.0.0 - - org.eclipse.hawkbit - hawkbit-examples-parent - 0.2.0-SNAPSHOT - - hawkbit-example-ddi-client + + 4.0.0 + + org.eclipse.hawkbit + hawkbit-examples-parent + 0.2.0-SNAPSHOT + + hawkbit-example-ddi-client - hawkbit-example-ddi-client - - + hawkbit-example-ddi-client + + org.springframework.cloud @@ -22,32 +22,32 @@ - - - - org.eclipse.hawkbit + + + + org.eclipse.hawkbit hawkbit-ddi-api ${project.version} - + org.springframework.cloud spring-cloud-starter-feign - + com.netflix.feign feign-core - + 8.14.2 - + com.netflix.feign feign-jackson - - 8.14.2 + + 8.14.2 - + javax.servlet javax.servlet-api @@ -56,11 +56,29 @@ org.springframework.plugin spring-plugin-core - - - junit - junit - test - - + + com.fasterxml.jackson.core + jackson-databind + + + + + commons-io + commons-io + 2.5 + + + + + + junit + junit + test + + + ru.yandex.qatools.allure + allure-junit-adaptor + test + + diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/Application.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/Application.java deleted file mode 100644 index 86ccf195e..000000000 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/Application.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. - */ -package org.eclipse.hawkbit.ddi.client; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.context.annotation.Bean; - -import feign.Contract; - -/** - * @author Jonathan Knoblauch - * - */ -@SpringBootApplication -@EnableFeignClients -public class Application { - - @Autowired - private DdiExampleClient ddiClient; - - public static void main(final String[] args) { - new SpringApplicationBuilder().showBanner(false).sources(Application.class).run(args); - - // TODO .encoder(new JacksonEncoder()) - // .decoder(new ResponseEntityDecoder(new JacksonDecoder())); - - } - - // @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(); - } - -} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/ApplicationJsonRequestHeaderInterceptor.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/ApplicationJsonRequestHeaderInterceptor.java index df43444d6..97a3e4395 100644 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/ApplicationJsonRequestHeaderInterceptor.java +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/ApplicationJsonRequestHeaderInterceptor.java @@ -21,10 +21,11 @@ public class ApplicationJsonRequestHeaderInterceptor implements RequestIntercept @Override public void apply(final RequestTemplate template) { - template.header("Accept", MediaType.APPLICATION_JSON_VALUE); - // template.header("Accept", - // EnableHypermediaSupport.HypermediaType.HAL); + template.header("Accept", MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE, + MediaType.TEXT_PLAIN_VALUE); + // template.header("Accept", MediaType.APPLICATION_OCTET_STREAM_VALUE); template.header("Content-Type", MediaType.APPLICATION_JSON_VALUE); + } } diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDecoder.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDecoder.java new file mode 100644 index 000000000..90fc0e7bd --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDecoder.java @@ -0,0 +1,55 @@ +/** + * 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.ddi.client; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; +import org.springframework.hateoas.hal.Jackson2HalModule; +import org.springframework.http.ResponseEntity; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import feign.FeignException; +import feign.Response; +import feign.codec.DecodeException; +import feign.codec.Decoder; +import feign.jackson.JacksonDecoder; + +/** + * Decoder for DDI client. + * + */ +public class DdiDecoder implements Decoder { + + ObjectMapper mapper; + + public DdiDecoder() { + mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .registerModule(new Jackson2HalModule()); + } + + @Override + public Object decode(final Response response, final Type type) throws IOException, DecodeException, FeignException { + + final Map> header = response.headers(); + final String contentType = String.valueOf(header.get("Content-Type")); + // TODO parameter verwenden + if (contentType.equals("[application/octet-stream]")) { + return ResponseEntity.ok(response.body().asInputStream()); + } + final ResponseEntityDecoder responseEntityDecoder = new ResponseEntityDecoder(new JacksonDecoder(mapper)); + return responseEntityDecoder.decode(response, type); + } + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDefaultFeignClient.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDefaultFeignClient.java index 73b1d4f81..d6e9dde96 100644 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDefaultFeignClient.java +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiDefaultFeignClient.java @@ -1,20 +1,19 @@ /** - * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + * 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.ddi.client; import org.eclipse.hawkbit.ddi.client.resource.RootControllerResourceClient; -import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; -import org.springframework.hateoas.hal.Jackson2HalModule; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import feign.Feign; import feign.Feign.Builder; import feign.Logger; import feign.Logger.Level; -import feign.jackson.JacksonDecoder; import feign.jackson.JacksonEncoder; /** @@ -30,15 +29,18 @@ public class DdiDefaultFeignClient { private final String tenant; public DdiDefaultFeignClient(final String baseUrl, final String tenant) { - - final ObjectMapper mapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .registerModule(new Jackson2HalModule()); - feignBuilder = Feign.builder().contract(new IgnoreMultipleConsumersProducersSpringMvcContract()) .requestInterceptor(new ApplicationJsonRequestHeaderInterceptor()).logLevel(Level.FULL) - .logger(new Logger.ErrorLogger()).encoder(new JacksonEncoder()) - .decoder(new ResponseEntityDecoder(new JacksonDecoder(mapper))); + .logger(new Logger.ErrorLogger()).encoder(new JacksonEncoder()).decoder(new DdiDecoder()); + + if (baseUrl == null) { + throw new IllegalStateException("A baseUrl has to be set"); + } + + if (tenant == null) { + throw new IllegalStateException("A tenant has to be set"); + } + this.baseUrl = baseUrl; this.tenant = tenant; @@ -50,10 +52,12 @@ public class DdiDefaultFeignClient { public RootControllerResourceClient getRootControllerResourceClient() { - String rootControllerResourcePath = this.baseUrl + RootControllerResourceClient.PATH; - rootControllerResourcePath = rootControllerResourcePath.replace("{tenant}", tenant); // TODO tenant null throw exception if (rootControllerResourceClient == null) { + + String rootControllerResourcePath = this.baseUrl + RootControllerResourceClient.PATH; + rootControllerResourcePath = rootControllerResourcePath.replace("{tenant}", tenant); + rootControllerResourceClient = feignBuilder.target(RootControllerResourceClient.class, rootControllerResourcePath); } diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiExampleClient.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiExampleClient.java index c0fb6ff9c..e0a01e814 100644 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiExampleClient.java +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiExampleClient.java @@ -1,26 +1,51 @@ /** - * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + * 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.ddi.client; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; +import org.eclipse.hawkbit.ddi.client.strategy.PersistenceStrategy; +import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback; +import org.eclipse.hawkbit.ddi.json.model.DdiArtifact; +import org.eclipse.hawkbit.ddi.json.model.DdiChunk; import org.eclipse.hawkbit.ddi.json.model.DdiControllerBase; import org.eclipse.hawkbit.ddi.json.model.DdiDeploymentBase; +import org.eclipse.hawkbit.ddi.json.model.DdiResult; +import org.eclipse.hawkbit.ddi.json.model.DdiResult.FinalResult; +import org.eclipse.hawkbit.ddi.json.model.DdiStatus; +import org.eclipse.hawkbit.ddi.json.model.DdiStatus.ExecutionStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.hateoas.Link; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -//@Component public class DdiExampleClient implements Runnable { + private static final Logger LOGGER = LoggerFactory.getLogger(DdiExampleClient.class); + private final String controllerId; + private Long actionIdOfLastInstalltion; + private final DdiDefaultFeignClient ddiDefaultFeignClient; + private final long pollingIntervalInMillis; + private final PersistenceStrategy persistenceStrategy; - final DdiDefaultFeignClient ddiDefaultFeignClient; - - public DdiExampleClient(final String baseUrl, final String controllerId, final String tenant) { - super(); + public DdiExampleClient(final String baseUrl, final String controllerId, final String tenant, + final long pollingIntervalInMillis, final PersistenceStrategy persistenceStrategy) { this.controllerId = controllerId; - ddiDefaultFeignClient = new DdiDefaultFeignClient(baseUrl, tenant); + this.ddiDefaultFeignClient = new DdiDefaultFeignClient(baseUrl, tenant); + this.actionIdOfLastInstalltion = null; + this.pollingIntervalInMillis = pollingIntervalInMillis; + this.persistenceStrategy = persistenceStrategy; } @Override @@ -28,65 +53,139 @@ public class DdiExampleClient implements Runnable { ResponseEntity response; - for (int i = 0; i < 20; i++) { - + while (!Thread.currentThread().isInterrupted()) { response = ddiDefaultFeignClient.getRootControllerResourceClient().getControllerBase(controllerId); final DdiControllerBase controllerBase = response.getBody(); final Link controllerDeploymentBaseLink = controllerBase.getLink("deploymentBase"); if (controllerDeploymentBaseLink != null) { - // TOD actung download nur einmal starten - startDownload(controllerDeploymentBaseLink); + final Long actionId = getActionIdOutOfLink(controllerDeploymentBaseLink); + final Integer resource = getResourceOutOfLink(controllerDeploymentBaseLink); + if (actionId != actionIdOfLastInstalltion) { + + startDownload(actionId, resource); + + simulateSuccessfulInstallation(actionId); + + actionIdOfLastInstalltion = actionId; + } } try { - Thread.sleep(2000); + Thread.sleep(pollingIntervalInMillis); + System.out.println("polling ..."); } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOGGER.error("Error during sleep"); } } } - public void startDdiClient() { - - // - - // TODO notify every 10 seconds on the rollout server - - // TODO if new update available -> start download and installation - // process - // report status messages - - } - - private void startDownload(final Link controllerDeploymentBaseLink) { - - // controllerDeploymentBaseLink. - - // final List varibles = controllerDeploymentBaseLink.get - - final String link = controllerDeploymentBaseLink.getHref(); - final String[] segs = link.split(Pattern.quote("/")); - final String[] ending = segs[8].split(Pattern.quote("?")); - final String actionId = ending[0]; - final String resource = ending[1].substring(2); + private void startDownload(final Long actionId, final Integer resource) { + // resource has not been downloaded and installed final ResponseEntity respone = ddiDefaultFeignClient.getRootControllerResourceClient() .getControllerBasedeploymentAction(controllerId, Long.valueOf(actionId), Integer.valueOf(resource)); - final DdiDeploymentBase ddiDeploymentBase = respone.getBody(); - - final Link downloadLink = ddiDeploymentBase.getDeployment().getChunks().get(0).getArtifacts().get(0) - .getLink("download"); - - System.out.println("download startet ...."); - + final List chunks = ddiDeploymentBase.getDeployment().getChunks(); + for (final DdiChunk chunk : chunks) { + final List artifactList = chunk.getArtifacts(); + final Link downloadLink = ddiDeploymentBase.getDeployment().getChunks().get(0).getArtifacts().get(0) + .getLink("download-http"); + final String[] downloadLinkSep = downloadLink.getHref().split(Pattern.quote("/")); + final Long softwareModuleId = Long.valueOf(downloadLinkSep[8]); + // download all artifacts + for (final DdiArtifact ddiArtifact : artifactList) { + downloadArtifact(actionId, softwareModuleId, ddiArtifact.getFilename()); + } + } } - private void startSimulatedInstalltion() { + private void downloadArtifact(final Long actionId, final Long softwareModuleId, final String artifact) { + sendFeedBackMessage(actionId, ExecutionStatus.PROCEEDING, FinalResult.NONE, + "Starting download of artifact " + artifact); + System.out.println("Starting download for artifact " + artifact); + + final ResponseEntity responseDownloadArtifact = ddiDefaultFeignClient + .getRootControllerResourceClient().downloadArtifact(controllerId, softwareModuleId, artifact); + final HttpStatus statsuCode = responseDownloadArtifact.getStatusCode(); + System.out.println("Finished download with stataus " + statsuCode); + persistenceStrategy.handleInputStream(responseDownloadArtifact.getBody(), artifact); + + sendFeedBackMessage(actionId, ExecutionStatus.PROCEEDING, FinalResult.NONE, "Downloaded artifact " + artifact); } + private void sendFeedBackMessage(final Long actionId, final ExecutionStatus executionStatus, + final FinalResult finalResult, final String message) { + + final DdiResult result = new DdiResult(finalResult, null); + final List details = new ArrayList<>(); + details.add(message); + final DdiStatus ddiStatus = new DdiStatus(executionStatus, result, details); + final String time = null; + final DdiActionFeedback feedback = new DdiActionFeedback(actionId, time, ddiStatus); + final ResponseEntity response = ddiDefaultFeignClient.getRootControllerResourceClient() + .postBasedeploymentActionFeedback(feedback, controllerId, actionId); + + final HttpStatus statsuCode = response.getStatusCode(); + System.out.println("Message send with stataus " + statsuCode); + } + + private void simulateSuccessfulInstallation(final Long actionId) { + sendFeedBackMessage(actionId, ExecutionStatus.PROCEEDING, FinalResult.SUCESS, + "Simulated installation successful"); + } + + private Long getActionIdOutOfLink(final Link controllerDeploymentBaseLink) { + final String[] ending = splitControllerDeploymentBaseLinkInActionIdAndResource(controllerDeploymentBaseLink); + return Long.valueOf(ending[0]); + } + + private Integer getResourceOutOfLink(final Link controllerDeploymentBaseLink) { + final String[] ending = splitControllerDeploymentBaseLinkInActionIdAndResource(controllerDeploymentBaseLink); + return Integer.valueOf(ending[1].substring(2)); + } + + private String[] splitControllerDeploymentBaseLinkInActionIdAndResource(final Link controllerDeploymentBaseLink) { + final String link = controllerDeploymentBaseLink.getHref(); + final String[] segments = link.split(Pattern.quote("/")); + return segments[8].split(Pattern.quote("?")); + } + + // private RootControllerResourceClient getDownloadFeignClient() { + // + // final Builder feignBuilder = Feign.builder().contract(new + // IgnoreMultipleConsumersProducersSpringMvcContract()) + // .requestInterceptor(new + // ApplicationJsonRequestHeaderInterceptor()).logLevel(Level.FULL) + // .logger(new Logger.ErrorLogger()).encoder(new + // JacksonEncoder()).decoder(new Decoder() { + // @Override + // public Object decode(final Response response, final Type type) + // throws IOException, DecodeException, FeignException { + // + // // TODO download + // final InputStream stream = response.body().asInputStream(); + // + // final FileSystem local = FileSystems.getDefault(); + // + // System.out.println("Status is " + response.status()); + // + // final ResponseEntity test = new ResponseEntity( + // HttpStatus.valueOf(response.status())); + // + // return test; + // } + // }); + // + // final RootControllerResourceClient rootControllerResourceClient = + // feignBuilder + // .target(RootControllerResourceClient.class, + // "http://localhost:8080/DEFAULT/controller/v1"); + // + // return rootControllerResourceClient; + // + // } + } diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/resource/RootControllerResourceClient.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/resource/RootControllerResourceClient.java index 69ae96d84..76867af98 100644 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/resource/RootControllerResourceClient.java +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/resource/RootControllerResourceClient.java @@ -1,5 +1,10 @@ /** - * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + * 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.ddi.client.resource; diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/DoNotSaveArtifactsStrategy.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/DoNotSaveArtifactsStrategy.java new file mode 100644 index 000000000..15ea10829 --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/DoNotSaveArtifactsStrategy.java @@ -0,0 +1,29 @@ +/** + * 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.ddi.client.strategy; + +import java.io.InputStream; + +/** + * @author Jonathan Knoblauch + * + */ +public class DoNotSaveArtifactsStrategy implements PersistenceStrategy { + + @Override + public String getPersistenceStrategy() { + return "nosave"; + } + + @Override + public void handleInputStream(final InputStream in, final String artifactName) { + // down but do not save + } + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/PersistenceStrategy.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/PersistenceStrategy.java new file mode 100644 index 000000000..1c5c309e1 --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/PersistenceStrategy.java @@ -0,0 +1,23 @@ +/** + * 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.ddi.client.strategy; + +import java.io.InputStream; + +/** + * @author Jonathan Knoblauch + * + */ +public interface PersistenceStrategy { + + public String getPersistenceStrategy(); + + public void handleInputStream(InputStream in, String artifactName); + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/SaveArtifactsStrategy.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/SaveArtifactsStrategy.java new file mode 100644 index 000000000..ad1c573b1 --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/strategy/SaveArtifactsStrategy.java @@ -0,0 +1,45 @@ +/** + * 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.ddi.client.strategy; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.google.common.io.ByteStreams; + +/** + * @author Jonathan Knoblauch + * + */ +public class SaveArtifactsStrategy implements PersistenceStrategy { + + @Override + public String getPersistenceStrategy() { + + return "save"; + } + + @Override + public void handleInputStream(final InputStream in, final String artifactName) { + + final File file = new File("C:\\testdownload\\" + artifactName); + + try { + final OutputStream out = new FileOutputStream(file); + ByteStreams.copy(in, out); + } catch (final IOException e) { + e.printStackTrace(); + // TODO throw + } + } + +} diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiArtifactStoreControllerRestApi.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiArtifactStoreControllerRestApi.java index ab49be1c1..dc8b4bf96 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiArtifactStoreControllerRestApi.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiArtifactStoreControllerRestApi.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ddi.rest.api; +import java.io.InputStream; + import org.eclipse.hawkbit.ddi.json.model.DdiArtifact; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -42,7 +44,7 @@ public interface DdiArtifactStoreControllerRestApi { */ @RequestMapping(method = RequestMethod.GET, value = DdiRestConstants.ARTIFACT_DOWNLOAD_BY_FILENAME + "/{fileName}") @ResponseBody - public ResponseEntity downloadArtifactByFilename(@PathVariable("fileName") final String fileName, + public ResponseEntity downloadArtifactByFilename(@PathVariable("fileName") final String fileName, @AuthenticationPrincipal final String targetid); diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java index 8ba4068a7..45382faf5 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java @@ -3,6 +3,7 @@ */ package org.eclipse.hawkbit.ddi.rest.api; +import java.io.InputStream; import java.lang.annotation.Target; import java.util.List; @@ -80,7 +81,7 @@ public interface DdiRootControllerRestApi { * {@link HttpStatus#PARTIAL_CONTENT}. */ @RequestMapping(method = RequestMethod.GET, value = "/{targetid}/softwaremodules/{softwareModuleId}/artifacts/{fileName}") - ResponseEntity downloadArtifact(@PathVariable("targetid") final String targetid, + ResponseEntity downloadArtifact(@PathVariable("targetid") final String targetid, @PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("fileName") final String fileName); diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java index b2954d363..8552e686d 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ddi.rest.resource; import java.io.IOException; +import java.io.InputStream; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -68,7 +69,7 @@ public class DdiArtifactStoreController implements DdiArtifactStoreControllerRes private RequestResponseContextHolder requestResponseContextHolder; @Override - public ResponseEntity downloadArtifactByFilename(@PathVariable("fileName") final String fileName, + public ResponseEntity downloadArtifactByFilename(@PathVariable("fileName") final String fileName, @AuthenticationPrincipal final String targetid) { final List foundArtifacts = artifactManagement.findLocalArtifactByFilename(fileName); @@ -80,7 +81,7 @@ public class DdiArtifactStoreController implements DdiArtifactStoreControllerRes if (foundArtifacts.size() > 1) { LOG.warn("Software artifact name {} is not unique. We will use the first entry.", fileName); } - ResponseEntity result; + ResponseEntity result; final LocalArtifact artifact = foundArtifacts.get(0); final String ifMatch = requestResponseContextHolder.getHttpServletRequest().getHeader("If-Match"); diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java index 3df0916c0..c3aea102e 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ddi.rest.resource; import java.io.IOException; +import java.io.InputStream; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -138,10 +139,10 @@ public class DdiRootController implements DdiRootControllerRestApi { } @Override - public ResponseEntity downloadArtifact(@PathVariable("targetid") final String targetid, + public ResponseEntity downloadArtifact(@PathVariable("targetid") final String targetid, @PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("fileName") final String fileName) { - ResponseEntity result; + ResponseEntity result; final Target target = controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(requestResponseContextHolder.getHttpServletRequest(), diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java index 4b50dc8f5..ea6dccc7e 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.mgmt.rest.api; +import java.io.InputStream; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -36,7 +38,7 @@ public interface MgmtDownloadArtifactRestApi { */ @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}/download") @ResponseBody - ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("artifactId") final Long artifactId); } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java index de01a917a..077efa84c 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import java.io.InputStream; + import javax.servlet.http.HttpServletRequest; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; @@ -60,7 +62,7 @@ public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi */ @Override @ResponseBody - public ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + public ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("artifactId") final Long artifactId) { final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java index 827506048..96f30cc87 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java @@ -61,7 +61,7 @@ public final class RestResourceConversionHelper { * * @return http code */ - public static ResponseEntity writeFileResponse(final LocalArtifact artifact, + public static ResponseEntity writeFileResponse(final LocalArtifact artifact, final HttpServletResponse servletResponse, final HttpServletRequest request, final DbArtifact file) { return writeFileResponse(artifact, servletResponse, request, file, null, null); } @@ -96,11 +96,11 @@ public final class RestResourceConversionHelper { * * @see https://tools.ietf.org/html/rfc7233 */ - public static ResponseEntity writeFileResponse(final LocalArtifact artifact, + public static ResponseEntity writeFileResponse(final LocalArtifact artifact, final HttpServletResponse response, final HttpServletRequest request, final DbArtifact file, final CacheWriteNotify cacheWriteNotify, final Long statusId) { - ResponseEntity result = null; + ResponseEntity result = null; final String etag = artifact.getSha1Hash(); final Long lastModified = artifact.getLastModifiedAt() != null ? artifact.getLastModifiedAt() @@ -181,9 +181,9 @@ public final class RestResourceConversionHelper { } } - private static ResponseEntity extractRange(final HttpServletResponse response, final long length, + private static ResponseEntity extractRange(final HttpServletResponse response, final long length, final List ranges, final String range) { - ResponseEntity result = null; + ResponseEntity result = null; if (ranges.isEmpty()) { for (final String part : range.substring(6).split(",")) { long start = sublong(part, 0, part.indexOf('-'));