diff --git a/examples/hawkbit-example-ddi-client/pom.xml b/examples/hawkbit-example-ddi-client/pom.xml index 7630a5a9e..8ce1749dd 100644 --- a/examples/hawkbit-example-ddi-client/pom.xml +++ b/examples/hawkbit-example-ddi-client/pom.xml @@ -7,20 +7,54 @@ hawkbit-examples-parent 0.2.0-SNAPSHOT - org.eclipse.hawkbit hawkbit-example-ddi-client - 0.2.0-SNAPSHOT + hawkbit-example-ddi-client - http://maven.apache.org - - UTF-8 - + + + + + org.springframework.cloud + spring-cloud-netflix + 1.0.7.RELEASE + pom + import + + + + - + + org.eclipse.hawkbit + hawkbit-ddi-api + ${project.version} + + + org.springframework.cloud + spring-cloud-starter-feign + + + com.netflix.feign + feign-core + + 8.16.0 + + + com.netflix.feign + feign-jackson + + 8.16.0 + + + javax.servlet + javax.servlet-api + + + + junit junit - 3.8.1 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 new file mode 100644 index 000000000..e230a77da --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/Application.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.ddi.client; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.netflix.feign.EnableFeignClients; + +/** + * @author Jonathan Knoblauch + * + */ +@SpringBootApplication +@EnableFeignClients +public class Application { + + public static void main(final String[] args) { + new SpringApplicationBuilder().showBanner(false).sources(Application.class).run(args); + } + +} 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 new file mode 100644 index 000000000..680da74f1 --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/ApplicationJsonRequestHeaderInterceptor.java @@ -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.ddi.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); + } + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiClient.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiClient.java new file mode 100644 index 000000000..08b398b0f --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/DdiClient.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.ddi.client; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.hawkbit.ddi.client.resource.RootControllerResourceClient; +import org.eclipse.hawkbit.ddi.json.model.DdiControllerBase; +import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; +import org.springframework.http.ResponseEntity; + +import feign.Feign; +import feign.Logger; +import feign.Logger.Level; +import feign.jackson.JacksonDecoder; +import feign.jackson.JacksonEncoder; + +public class DdiClient { + + @Autowired + private HttpServletRequest request; + + @Autowired + private HttpServletResponse response; + + private final String controllerId; + private final String name; + private final String description; + private RootControllerResourceClient rootControllerResourceClient; + private String rootControllerResourcePath; + + public DdiClient(final String rolloutsUrl, final String controllerId, final String name, final String description, + final String tenant) { + super(); + this.controllerId = controllerId; + this.name = name; + this.description = description; + rootControllerResourcePath = rolloutsUrl + DdiRestConstants.BASE_V1_REQUEST_MAPPING; + rootControllerResourcePath = rootControllerResourcePath.replace("{tenant}", tenant); + + createFeignClient(); + } + + private void createFeignClient() { + + // BasicAuthRequestInterceptor TODO + + final Feign.Builder feignBuilder = Feign.builder() + .contract(new IgnoreMultipleConsumersProducersSpringMvcContract()) + .requestInterceptor(new ApplicationJsonRequestHeaderInterceptor()).logLevel(Level.FULL) + .logger(new Logger.ErrorLogger()).encoder(new JacksonEncoder()) + .decoder(new ResponseEntityDecoder(new JacksonDecoder())); + // TODO implement feign client encoder to handle MultiPartFile + // .requestInterceptor(new BasicAuthRequestInterceptor(tenant + "\\" + + // user, password)) + + rootControllerResourceClient = feignBuilder.target(RootControllerResourceClient.class, + rootControllerResourcePath); + + } + + public void startDdiClient() { + + // final HttpServletRequest request; + + // final HttpSession mySession = request.getSession(); + + // final HttpServletRequest request = new; + + final ResponseEntity response = rootControllerResourceClient.getControllerBase("test", + request); + final DdiControllerBase controllerBase = response.getBody(); + + // TODO notify every 10 seconds on the rollout server + + // TODO if new update available -> start download and installation + // process + // report status messages + + } + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/IgnoreMultipleConsumersProducersSpringMvcContract.java b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/IgnoreMultipleConsumersProducersSpringMvcContract.java new file mode 100644 index 000000000..c1c24b9ec --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/IgnoreMultipleConsumersProducersSpringMvcContract.java @@ -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.ddi.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); + } + } +} 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 new file mode 100644 index 000000000..395096a6e --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/main/java/org/eclipse/hawkbit/ddi/client/resource/RootControllerResourceClient.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.ddi.client.resource; + +import org.eclipse.hawkbit.ddi.rest.api.DdiRootControllerRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the Rootcontroller resource of the DDI API. + */ +@FeignClient(url = "${hawkbit.url:localhost:8080}/{tenant}/controller/v1") +public interface RootControllerResourceClient extends DdiRootControllerRestApi { + +} diff --git a/examples/hawkbit-example-ddi-client/src/main/java/org/hawkbit/example/ddi/client/App.java b/examples/hawkbit-example-ddi-client/src/main/java/org/hawkbit/example/ddi/client/App.java deleted file mode 100644 index cd85d3a8b..000000000 --- a/examples/hawkbit-example-ddi-client/src/main/java/org/hawkbit/example/ddi/client/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.hawkbit.example.ddi.client; - -/** - * Hello world! - * - */ -public class App -{ - public static void main( String[] args ) - { - System.out.println( "Hello World!" ); - } -} diff --git a/examples/hawkbit-example-ddi-client/src/test/java/org/eclipse/hawkbit/example/ddi/client/AppTest.java b/examples/hawkbit-example-ddi-client/src/test/java/org/eclipse/hawkbit/example/ddi/client/AppTest.java new file mode 100644 index 000000000..64f34c8ff --- /dev/null +++ b/examples/hawkbit-example-ddi-client/src/test/java/org/eclipse/hawkbit/example/ddi/client/AppTest.java @@ -0,0 +1,18 @@ +package org.eclipse.hawkbit.example.ddi.client; + +import org.eclipse.hawkbit.ddi.client.DdiClient; +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest { + + @Test + public void AppTest() { + + final DdiClient ddiClient = new DdiClient("localhost:8080", "mytest", "mytest", "desc", "DEFAULT"); + ddiClient.startDdiClient(); + } + +} diff --git a/examples/hawkbit-example-ddi-client/src/test/java/org/hawkbit/example/ddi/client/AppTest.java b/examples/hawkbit-example-ddi-client/src/test/java/org/hawkbit/example/ddi/client/AppTest.java deleted file mode 100644 index 395886a2d..000000000 --- a/examples/hawkbit-example-ddi-client/src/test/java/org/hawkbit/example/ddi/client/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.hawkbit.example.ddi.client; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -}