diff --git a/src/.gitignore b/src/.gitignore index db07b3a..6576501 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,3 +3,7 @@ # run "dep ensure --vendor-only" to download the dependencies to vendor/ based # on the Gopkg.{toml,lock} files in that directory. vendor/ +tamagotchi-service/target +tamagotchi-service/.idea +*.iml + diff --git a/src/tamagotchi-service/.gitignore b/src/tamagotchi-service/.gitignore new file mode 100644 index 0000000..5033dcd --- /dev/null +++ b/src/tamagotchi-service/.gitignore @@ -0,0 +1,32 @@ +.mta +.che + + +/**/node_modules +/**/target +/**/dist + +/**/.project +/**/.settings +/**/.classpath +/**/.springBeans +/**/.factorypath +/**/.idea + +// Generated Artifacts +/**/edmx/ +/**/gen +/**/src/generated +/**/dist +/**/webapp/localService/metadata.xml + + + + +// Files and folders generated by WebIDE build and not to be committed +/uideployer/resources/ +/uideployer/deploymentTemp/ + + +/**/package-lock.json +/**/*.mtar \ No newline at end of file diff --git a/src/tamagotchi-service/app.yaml b/src/tamagotchi-service/app.yaml new file mode 100644 index 0000000..23e61a6 --- /dev/null +++ b/src/tamagotchi-service/app.yaml @@ -0,0 +1,8 @@ +runtime: java11 +entrypoint: java -jar target/tamagotchi-service-0.1.0.jar +inbound_services: + - warmup +automatic_scaling: + max_instances: 1 + min_instances: 1 + diff --git a/src/tamagotchi-service/pom.xml b/src/tamagotchi-service/pom.xml new file mode 100644 index 0000000..1800402 --- /dev/null +++ b/src/tamagotchi-service/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + com.sap + tamagotchi-service + 0.1.0 + + + 1.8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 2.1.6.RELEASE + + + + + + com.google.cloud + libraries-bom + 2.9.0 + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-test + + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + com.google.cloud + google-cloud-pubsub + + + com.jayway.jsonpath + json-path + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + com.google.appengine + appengine-maven-plugin + 1.9.77 + + + + + diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/Application.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/Application.java new file mode 100644 index 0000000..5c4e423 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/Application.java @@ -0,0 +1,11 @@ +package com.sap.tamagotchi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/configuration/ApplicationConfiguration.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/configuration/ApplicationConfiguration.java new file mode 100644 index 0000000..88c0409 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/configuration/ApplicationConfiguration.java @@ -0,0 +1,24 @@ +package com.sap.tamagotchi.configuration; + + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ApplicationConfiguration { + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true); + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + return objectMapper; + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/DeviceController.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/DeviceController.java new file mode 100644 index 0000000..08a44fc --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/DeviceController.java @@ -0,0 +1,65 @@ +package com.sap.tamagotchi.controller; + +import static com.sap.tamagotchi.model.Color.RED; +import static com.sap.tamagotchi.model.Color.YELLOW; +import static org.springframework.http.ResponseEntity.ok; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.sap.tamagotchi.model.Color; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.sap.tamagotchi.model.CreateDevicePayload; +import com.sap.tamagotchi.model.Device; +import com.sap.tamagotchi.service.TamagotchiService; + +@RestController +public class DeviceController { + + private final TamagotchiService tamagotchiService; + + @Autowired + public DeviceController(TamagotchiService tamagotchiService) { + this.tamagotchiService = tamagotchiService; + } + + private static Color mapColor(String productId) { + switch (productId) { + case "66VCHSJNUP": + return RED; + default: + return YELLOW; + } + } + + @RequestMapping("/devices/{deviceId}") + public Device getDevice(String deviceId) { + return tamagotchiService.getDevice(deviceId); + } + + @RequestMapping("/devices") + public Collection getDevices() { + return tamagotchiService.getDevices(); + } + + @PostMapping("/devices") + public ResponseEntity createDevice(@RequestBody Collection payload) { + List devices = new ArrayList<>(); + for (CreateDevicePayload p : payload) { + devices.add(tamagotchiService.createDevice(new Device(p.getOwner(), mapColor(p.getProductId())))); + } + return ok(devices); + } + + @RequestMapping("/_ah/warmup") + public String warmup() { + return "warming up"; + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/OwnerController.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/OwnerController.java new file mode 100644 index 0000000..557cdca --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/controller/OwnerController.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2019, SAP SE, All rights reserved. + */ +package com.sap.tamagotchi.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.sap.tamagotchi.model.Owner; + +@RestController +@RequestMapping("/owner") +public class OwnerController { + + @Autowired + Owner owner; + + @GetMapping() + public void killTamagotchi() { + owner.killRendomDevice(); + } + +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Care.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Care.java new file mode 100644 index 0000000..5337c55 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Care.java @@ -0,0 +1,24 @@ +package com.sap.tamagotchi.model; + +public class Care { + + private int feed = 0; + private int pet = 0; + + public int getFeed() { + return feed; + } + + public void setFeed(int feed) { + this.feed = feed; + } + + public int getPet() { + return pet; + } + + public void setPet(int pet) { + this.pet = pet; + } + +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Color.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Color.java new file mode 100644 index 0000000..82a9c2f --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Color.java @@ -0,0 +1,5 @@ +package com.sap.tamagotchi.model; + +public enum Color { + RED, YELLOW, BLUE, GREEN +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/CreateDevicePayload.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/CreateDevicePayload.java new file mode 100644 index 0000000..52f9782 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/CreateDevicePayload.java @@ -0,0 +1,25 @@ +package com.sap.tamagotchi.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CreateDevicePayload { + private final String userId; + private final String productId; + + @JsonCreator + public CreateDevicePayload(@JsonProperty("userId") String userId, @JsonProperty("productId") String productId) { + this.userId = userId; + this.productId = productId; + } + + @JsonProperty("userId") + public String getOwner() { + return userId; + } + + @JsonProperty("productId") + public String getProductId() { + return productId; + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DefunctNotification.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DefunctNotification.java new file mode 100644 index 0000000..1666c9a --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DefunctNotification.java @@ -0,0 +1,25 @@ +package com.sap.tamagotchi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class DefunctNotification implements IoTMessage { + + @JsonProperty("message") + private final String message; + + public DefunctNotification(String message) { + this.message = message; + } + + @JsonIgnore + @Override + public String getTopic() { + return "tamagotchi-defunct"; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Device.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Device.java new file mode 100644 index 0000000..58226ca --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Device.java @@ -0,0 +1,87 @@ +package com.sap.tamagotchi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.Instant; +import java.util.Queue; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Device { + + @JsonProperty("id") + private final String id = UUID.randomUUID().toString(); + @JsonProperty("owner") + private final String owner; + @JsonProperty("color") + private final Color color; + @JsonProperty("born") + private final Instant born = Instant.now(); + @JsonProperty("healthScore") + private int healthScore = 100; + private final Queue messages = new ConcurrentLinkedQueue<>(); + + public Device(String owner, Color color) { + this.owner = owner; + this.color = color; + } + + @JsonProperty("id") + public String getId() { + return id; + } + + @JsonProperty("owner") + public String getOwner() { + return owner; + } + + @JsonProperty("color") + public Color getColor() { + return color; + } + + @JsonProperty("born") + public String getBorn() { + return born.toString(); + } + + @JsonProperty("healthScore") + public int getHealthScore() { + return healthScore; + } + + @JsonProperty("isAlive") + public boolean isAlive() { + return healthScore > 1; + } + + @JsonIgnore + public void changeHealthScore(int delta) { + int oldScore = healthScore; + if (healthScore >= 1) { + healthScore += delta; + if (healthScore > 150) + healthScore /= 10; + } + + if (healthScore < 1) { + healthScore = 0; + messages.add(new DeviceEvent(id, owner, color, born, healthScore, oldScore, Instant.now())); + } else + messages.add(new DeviceEvent(id, owner, color, born, healthScore, null, Instant.now())); + } + + @JsonIgnore + public boolean hasMessages() { + return !messages.isEmpty(); + } + + @JsonIgnore + public Queue getMessages() { + return messages; + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DeviceEvent.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DeviceEvent.java new file mode 100644 index 0000000..d757795 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/DeviceEvent.java @@ -0,0 +1,95 @@ +package com.sap.tamagotchi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.Instant; + + +public class DeviceEvent implements IoTMessage { + + @JsonProperty("id") + private final String id; + @JsonProperty("owner") + private final String owner; + @JsonProperty("color") + private final Color color; + @JsonProperty("born") + private final Instant born; + @JsonProperty("healthScore") + private final Integer healthScore; + @JsonProperty("lastHealthScore") + private final Integer lastHealthScore; + @JsonProperty("eventTime") + private final Instant eventTime; + + public DeviceEvent(String id, String owner, Color color, Instant born, Integer healthScore, Integer lastHealthScore, Instant eventTime) { + this.id = id; + this.owner = owner; + this.color = color; + this.born = born; + this.healthScore = healthScore; + this.lastHealthScore = lastHealthScore; + this.eventTime = eventTime; + } + + @JsonProperty("id") + public String getId() { + return id; + } + + @JsonProperty("owner") + public String getOwner() { + return owner; + } + + @JsonProperty("color") + public Color getColor() { + return color; + } + + @JsonProperty("born") + public String getBorn() { + return born.toString(); + } + + @JsonProperty("healthScore") + public Integer getHealthScore() { + return healthScore; + } + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonProperty("lastHealthScore") + public Integer getLastHealthScore() { + return lastHealthScore; + } + + @JsonProperty("eventTime") + public String getEventTime() { + return eventTime.toString(); + } + + @JsonProperty("isAlive") + public boolean isAlive() { + return healthScore > 1; + } + + @JsonIgnore + @Override + public String getTopic() { + return "tamagotchi-events"; + } + + @Override + public String toString() { + return "DeviceEvent{" + + "id='" + id + '\'' + + ", owner='" + owner + '\'' + + ", color=" + color + + ", born=" + born + + ", healthScore=" + healthScore + + ", eventTime=" + eventTime + + '}'; + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/IoTMessage.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/IoTMessage.java new file mode 100644 index 0000000..1de2d9b --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/IoTMessage.java @@ -0,0 +1,5 @@ +package com.sap.tamagotchi.model; + +public interface IoTMessage { + String getTopic(); +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Owner.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Owner.java new file mode 100644 index 0000000..4f97ae8 --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/model/Owner.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2019, SAP SE, All rights reserved. + */ +package com.sap.tamagotchi.model; + +import static com.sap.tamagotchi.service.TamagotchiService.DEVICE_EVENT_PROCESSOR_SCHEDULE; + +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import com.sap.tamagotchi.service.TamagotchiService; + +@Service +@EnableScheduling +public class Owner { + + private TamagotchiService tamagotchiService; + + @Autowired + public Owner(TamagotchiService tamagotchiService) { + this.tamagotchiService = tamagotchiService; + } + + @Scheduled(fixedDelay = DEVICE_EVENT_PROCESSOR_SCHEDULE) + public void setData() { + for (Device d : tamagotchiService.getDevices()) { + + String userName = d.getOwner().substring(0, d.getOwner().indexOf("@")).toUpperCase(); + + int careAboutThePet = 0; + + for (int i = 0; i < userName.length(); i++) { + if (d.getColor().toString().indexOf(userName.charAt(i)) != -1) { + careAboutThePet++; + } + } + + Care care = new Care(); + + if (careAboutThePet == 0) { + care.setFeed(-5); + } else { + care.setFeed(5); + } + tamagotchiService.takeCare(d.getId(), care); + } + } + + @Scheduled(fixedDelay = 30000) + public void killRendomDevice() { + + Collection devices = tamagotchiService.getDevices(); + + if (devices != null && devices.iterator().hasNext()) { + Device first = devices.iterator().next(); + Care care = new Care(); + care.setFeed(-100000); + tamagotchiService.takeCare(first.getId(), care); + } + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/publisher/PublisherService.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/publisher/PublisherService.java new file mode 100644 index 0000000..fd9724a --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/publisher/PublisherService.java @@ -0,0 +1,82 @@ +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.IoTMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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()); + + // use the default project id + private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId(); + private final ObjectMapper mapper; + + @Autowired + public PublisherService(ObjectMapper mapper) { + this.mapper = mapper; + } + + public void publish(IoTMessage message) throws Exception { + if (message == null) { + LOGGER.info("received null message"); + return; + } + String topicId = message.getTopic(); + ProjectTopicName topicName = ProjectTopicName.of(PROJECT_ID, topicId); + Publisher publisher = null; + List> futures = new ArrayList<>(); + + try { + String stringMessage = mapper.writeValueAsString(message); + // 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(stringMessage); + PubsubMessage pubsubMessage = PubsubMessage.newBuilder() + .setData(data) + .build(); + + LOGGER.info("publish to message" + stringMessage); + + // Schedule a message to be published. Messages are automatically batched. + ApiFuture future = publisher.publish(pubsubMessage); + futures.add(future); + + } finally { + // Wait on any pending requests + List 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 "); + } + } +} diff --git a/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/service/TamagotchiService.java b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/service/TamagotchiService.java new file mode 100644 index 0000000..5f609de --- /dev/null +++ b/src/tamagotchi-service/src/main/java/com/sap/tamagotchi/service/TamagotchiService.java @@ -0,0 +1,109 @@ +package com.sap.tamagotchi.service; + +import java.lang.invoke.MethodHandles; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import com.sap.tamagotchi.model.Care; +import com.sap.tamagotchi.model.DefunctNotification; +import com.sap.tamagotchi.model.Device; +import com.sap.tamagotchi.publisher.PublisherService; + +@Service +@EnableScheduling +public class TamagotchiService { + + public static final long DEVICE_EVENT_PROCESSOR_SCHEDULE = 5000; + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private static final Map deviceRegistry = Collections.synchronizedMap(new HashMap<>()); + + private final PublisherService publisherService; + + @Autowired + public TamagotchiService(PublisherService publisherService) { + this.publisherService = publisherService; + } + + public Device getDevice(String deviceId) { + return deviceRegistry.get(deviceId); + } + + public Collection getDevices() { + return deviceRegistry.values(); + } + + public Set getDeviceIds() { + return deviceRegistry.keySet(); + } + + public Device createDevice(Device device) { + deviceRegistry.put(device.getId(), device); + return device; + } + + public void takeCare(String deviceId, Care care) { + Device device = deviceRegistry.get(deviceId); + if (device == null) { + return; + } + device.changeHealthScore(care.getFeed()); + device.changeHealthScore(care.getPet()); + } + + @Scheduled(fixedDelay = DEVICE_EVENT_PROCESSOR_SCHEDULE) + private void processDeviceEvents() { + deviceRegistry + .values() + .parallelStream() + .filter(Device::hasMessages) + .forEach(device -> { + while (device.getMessages().peek() != null) { + try { + publisherService.publish(device.getMessages().poll()); + } catch (Exception ex) { + LOGGER.error("processing device events failed: {}", ex.getMessage()); + } + } + }); + + // remove dead devices + deviceRegistry + .values() + .parallelStream() + .filter(device -> !device.isAlive()) + .forEach(device -> { + sendTamagotchiDefunctNotifiction(device.getId()); + deviceRegistry.remove(device.getId()); + LOGGER.info("{} has died", device.getId()); + }); + } + + private void sendTamagotchiDefunctNotifiction(String id) { + + Device device = deviceRegistry.get(id); + if (device == null || device.getId() == null || device.getOwner() == null) { + return; + } + String defunctMessage = String.format("Tamagotchi %s of %s passed away", device.getId(), device.getOwner()); + DefunctNotification defunctNotification = new DefunctNotification(defunctMessage); + try { + publisherService.publish(defunctNotification); + LOGGER.info("defunct notification sent for {}", device.getId()); + } catch (Exception ex) { + LOGGER.error("sendTamagotchiDefunctNotifiction failed: {}", ex.getMessage()); + } + } + +} diff --git a/src/tamagotchi-service/src/test/java/com/sap/tamagotchi/model/OwnerTest.java b/src/tamagotchi-service/src/test/java/com/sap/tamagotchi/model/OwnerTest.java new file mode 100644 index 0000000..35e2820 --- /dev/null +++ b/src/tamagotchi-service/src/test/java/com/sap/tamagotchi/model/OwnerTest.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2019, SAP SE, All rights reserved. + */ +package com.sap.tamagotchi.model; + +import static java.util.Arrays.asList; +import static org.mockito.Mockito.when; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; +import com.sap.tamagotchi.service.TamagotchiService;; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class OwnerTest { + + @Autowired + Owner owner; + + @MockBean + TamagotchiService tamagotchiService; + + Collection mockDevices; + + // @Before + // public void init() { + // MockitoAnnotations.initMocks(this); + // } + + @Test + public void testIt() { + when(tamagotchiService.getDevices()).thenReturn(asList(new Device("elisa@sap.com", Color.BLUE))); + owner.setData(); + + } +}