restructure service

This commit is contained in:
Tibor Tarnai 2019-12-10 15:48:12 +01:00
parent 873bf1e7bc
commit dfaa41cc33
12 changed files with 166 additions and 94 deletions

View file

@ -19,6 +19,18 @@
<version>2.1.6.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>2.9.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -29,6 +41,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>

View file

@ -1,4 +1,4 @@
package hello;
package com.sap.tamagotchi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View file

@ -0,0 +1,28 @@
package com.sap.tamagotchi.controller;
import java.util.concurrent.atomic.AtomicLong;
import com.sap.tamagotchi.model.Device;
import com.sap.tamagotchi.publisher.PublisherService;
import com.sap.tamagotchi.service.TamagotchiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeviceController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
private final TamagotchiService tamagotchiService;
@Autowired
public DeviceController(TamagotchiService tamagotchiService) {
this.tamagotchiService = tamagotchiService;
}
@RequestMapping("devices/{deviceId}")
public Device getDevice(String deviceId) {
return tamagotchiService.getDevice(deviceId);
}
}

View file

@ -0,0 +1,4 @@
package com.sap.tamagotchi.model;
public class Device {
}

View file

@ -0,0 +1,4 @@
package com.sap.tamagotchi.model;
public class DeviceEvent {
}

View file

@ -0,0 +1,13 @@
package com.sap.tamagotchi.model;
public class DummyMessage {
private final String message;
public DummyMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,7 @@
package com.sap.tamagotchi.model;
public interface IoTMessage {
String toMessage();
String getTopic();
}

View file

@ -0,0 +1,71 @@
package com.sap.tamagotchi.publisher;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.cloud.ServiceOptions;
import com.google.cloud.pubsub.v1.Publisher;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage;
import com.sap.tamagotchi.model.DummyMessage;
import com.sap.tamagotchi.model.IoTMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
@Service
public class PublisherService {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final ObjectMapper mapper = new ObjectMapper();
// use the default project id
private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
public void publish(IoTMessage message) throws Exception {
String topicId = message.getTopic();
ProjectTopicName topicName = ProjectTopicName.of(PROJECT_ID, topicId);
Publisher publisher = null;
List<ApiFuture<String>> futures = new ArrayList<>();
try {
// Create a publisher instance with default settings bound to the topic
publisher = Publisher.newBuilder(topicName).build();
LOGGER.info("publish to topic" + publisher.getTopicNameString());
// convert message to bytes
ByteString data = ByteString.copyFromUtf8(message.toMessage());
PubsubMessage pubsubMessage = PubsubMessage.newBuilder()
.setData(data)
.build();
LOGGER.info("publish to message" + message.toMessage());
// Schedule a message to be published. Messages are automatically batched.
ApiFuture<String> future = publisher.publish(pubsubMessage);
futures.add(future);
} finally {
// Wait on any pending requests
List<String> messageIds = ApiFutures.allAsList(futures).get();
for (String messageId : messageIds) {
System.out.println(messageId);
LOGGER.info("publish successful : " + messageId);
}
if (publisher != null) {
// When finished with the publisher, shutdown to free up resources.
publisher.shutdown();
}
if (messageIds.isEmpty())
LOGGER.info("no messages published ");
}
}
}

View file

@ -0,0 +1,22 @@
package com.sap.tamagotchi.service;
import com.sap.tamagotchi.model.Device;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Service
public class TamagotchiService {
private final Map<String, Device> deviceRegistry = new HashMap<>();
public Device getDevice(String deviceId) {
return deviceRegistry.get(deviceId);
}
public Collection<Device> getDevices() {
return deviceRegistry.values();
}
}

View file

@ -1,20 +0,0 @@
package hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}

View file

@ -1,19 +0,0 @@
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hello;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GreetingControllerTests {
@Autowired
private MockMvc mockMvc;
@Test
public void noParamGreetingShouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.content").value("Hello, World!"));
}
@Test
public void paramGreetingShouldReturnTailoredMessage() throws Exception {
this.mockMvc.perform(get("/greeting").param("name", "Spring Community"))
.andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.content").value("Hello, Spring Community!"));
}
}