diff --git a/.gitignore b/.gitignore index c4c5551..57462fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Project specific files *list.conf config.properties +/*.db +/application.properties # Created by https://www.gitignore.io diff --git a/build.gradle b/build.gradle index e812a00..7f6b199 100644 --- a/build.gradle +++ b/build.gradle @@ -37,6 +37,8 @@ dependencies { compile("org.springframework.boot:spring-boot-starter-hateoas") compile("org.springframework.boot:spring-boot-starter-jersey") compile("org.springframework.boot:spring-boot-starter-web") + compile("io.springfox:springfox-swagger2:2.0.2") + compile("io.springfox:springfox-swagger-ui:2.0.2") compile 'ch.dissem.jabit:jabit-domain:0.2.1-SNAPSHOT' compile 'ch.dissem.jabit:jabit-networking:0.2.1-SNAPSHOT' diff --git a/src/main/java/ch/dissem/bitmessage/server/JabitServerApplication.java b/src/main/java/ch/dissem/bitmessage/server/JabitServerApplication.java index f5f1681..83338ac 100644 --- a/src/main/java/ch/dissem/bitmessage/server/JabitServerApplication.java +++ b/src/main/java/ch/dissem/bitmessage/server/JabitServerApplication.java @@ -16,90 +16,15 @@ package ch.dissem.bitmessage.server; -import ch.dissem.bitmessage.BitmessageContext; -import ch.dissem.bitmessage.entity.BitmessageAddress; -import ch.dissem.bitmessage.entity.Plaintext; -import ch.dissem.bitmessage.server.entities.Broadcasts; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.context.annotation.ComponentScan; +import springfox.documentation.swagger2.annotations.EnableSwagger2; -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.inject.Inject; -import java.util.List; -import java.util.Set; -import java.util.Timer; - -import static ch.dissem.bitmessage.server.Converter.broadcasts; -import static ch.dissem.bitmessage.server.Converter.message; - -@CrossOrigin -@RestController @SpringBootApplication +@EnableSwagger2 +@ComponentScan(basePackageClasses = JabitServerController.class) public class JabitServerApplication { - private static final Logger LOG = LoggerFactory.getLogger(JabitServerApplication.class); - - private static final long HOUR = 60 * 60 * 1000l; // in ms - - private static final String CONFIG_FILE = "config.properties"; - private static final String PROPERTY_PORT = "port"; - - private static final int SHORTLIST_SIZE = 5; - - @Resource - private Set whitelist; - @Resource - private Set shortlist; - @Resource - private Set blacklist; - @Inject - private BitmessageContext ctx; - - @RequestMapping("status") - public String status() { - return ctx.status().toString(); - } - - @RequestMapping("read/{broadcastAddress}") - public Broadcasts read(@PathVariable String broadcastAddress) { - BitmessageAddress broadcaster = ctx.addresses().getAddress(broadcastAddress); - if (broadcaster == null) { - broadcaster = new BitmessageAddress(broadcastAddress); - } - - if (!whitelist.isEmpty() && !whitelist.contains(broadcaster.getAddress())) { - return broadcasts(broadcaster, message("Not Whitelisted", "Messages for " + broadcaster + - " can't be shown, as the sender isn't on the whitelist.")); - } - if (blacklist.contains(broadcaster.getAddress())) { - return broadcasts(broadcaster, message("Blacklisted", "Unfortunately, " + broadcaster + - " is on the blacklist, so it's messages can't be shown.")); - } - - if (!broadcaster.isSubscribed()) { - ctx.addSubscribtion(broadcaster); - } - List messages = ctx.messages().findMessages(broadcaster); - if (shortlist.contains(broadcaster.getAddress())) { - while (messages.size() > SHORTLIST_SIZE) { - ctx.messages().remove(messages.get(messages.size() - 1)); - messages.remove(messages.size() - 1); - } - } - return broadcasts(broadcaster, messages); - } - - @PostConstruct - public void setUp() { - ctx.startup(); - new Timer().scheduleAtFixedRate(new CleanupJob(ctx), 1 * HOUR, 24 * HOUR); - } public static void main(String[] args) { SpringApplication.run(JabitServerApplication.class, args); diff --git a/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java b/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java index 066921d..6dcd8f6 100644 --- a/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java +++ b/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java @@ -11,6 +11,8 @@ import ch.dissem.bitmessage.security.bc.BouncySecurity; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; import java.util.Set; @@ -71,4 +73,11 @@ public class JabitServerConfig { "# Bitmessage addresses in this file are being ignored and their broadcasts won't be returned.\n" ); } + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .build(); + } } diff --git a/src/main/java/ch/dissem/bitmessage/server/JabitServerController.java b/src/main/java/ch/dissem/bitmessage/server/JabitServerController.java new file mode 100644 index 0000000..9b458a9 --- /dev/null +++ b/src/main/java/ch/dissem/bitmessage/server/JabitServerController.java @@ -0,0 +1,96 @@ +package ch.dissem.bitmessage.server; + +import ch.dissem.bitmessage.BitmessageContext; +import ch.dissem.bitmessage.entity.BitmessageAddress; +import ch.dissem.bitmessage.entity.Plaintext; +import ch.dissem.bitmessage.server.entities.Broadcasts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.inject.Inject; +import java.util.List; +import java.util.Set; +import java.util.Timer; + +import static ch.dissem.bitmessage.server.Converter.broadcasts; +import static ch.dissem.bitmessage.server.Converter.message; +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +/** + * @author Christian Basler + */ +@CrossOrigin +@RestController +public class JabitServerController { + private static final Logger LOG = LoggerFactory.getLogger(JabitServerController.class); + + private static final long HOUR = 60 * 60 * 1000l; // in ms + + private static final String CONFIG_FILE = "config.properties"; + private static final String PROPERTY_PORT = "port"; + + private static final int SHORTLIST_SIZE = 5; + + @Resource + private Set<String> whitelist; + @Resource + private Set<String> shortlist; + @Resource + private Set<String> blacklist; + @Inject + private BitmessageContext ctx; + + @RequestMapping(value = "status", method = GET, produces = "application/json") + public String status() { + return ctx.status().toString(); + } + + @RequestMapping(value = "read/{broadcastAddress}", method = GET) + public Broadcasts read(@PathVariable String broadcastAddress) { + if ("test".equalsIgnoreCase(broadcastAddress)) { + return broadcasts( + new BitmessageAddress("BM-2cWhyaPxydemCeM8dWJUBmEo8iu7v2JptK"), + message("Test", "This is a test message. The rest service is running."), + message("Another Test", "And because it's such fun, a second message.") + ); + } + + BitmessageAddress broadcaster = ctx.addresses().getAddress(broadcastAddress); + if (broadcaster == null) { + broadcaster = new BitmessageAddress(broadcastAddress); + } + + if (!whitelist.isEmpty() && !whitelist.contains(broadcaster.getAddress())) { + return broadcasts(broadcaster, message("Not Whitelisted", "Messages for " + broadcaster + + " can't be shown, as the sender isn't on the whitelist.")); + } + if (blacklist.contains(broadcaster.getAddress())) { + return broadcasts(broadcaster, message("Blacklisted", "Unfortunately, " + broadcaster + + " is on the blacklist, so it's messages can't be shown.")); + } + + if (!broadcaster.isSubscribed()) { + ctx.addSubscribtion(broadcaster); + } + List<Plaintext> messages = ctx.messages().findMessages(broadcaster); + if (shortlist.contains(broadcaster.getAddress())) { + while (messages.size() > SHORTLIST_SIZE) { + ctx.messages().remove(messages.get(messages.size() - 1)); + messages.remove(messages.size() - 1); + } + } + return broadcasts(broadcaster, messages); + } + + @PostConstruct + public void setUp() { + ctx.startup(); + new Timer().scheduleAtFixedRate(new CleanupJob(ctx), 1 * HOUR, 24 * HOUR); + } +} diff --git a/webapp/app/elements/message-list/message-list.html b/webapp/app/elements/message-list/message-list.html index e8f82bd..8b4a80b 100644 --- a/webapp/app/elements/message-list/message-list.html +++ b/webapp/app/elements/message-list/message-list.html @@ -20,6 +20,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN float: right; font-size: 60%; } + .paper-font-body2 { white-space: pre-wrap; } @@ -41,7 +42,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN </template> <script> - (function() { + (function () { 'use strict'; Polymer({ @@ -59,16 +60,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN }, server: { type: String, - value: 'http://localhost:8080', + value: location.port === 5000 ? 'http://localhost:8080/' : '', notify: true } }, - toDate: function(timestamp) { + toDate: function (timestamp) { return new Date(timestamp * 1000).toLocaleString(); }, - getUrl: function(server, address) { - return server + '/read/' + address; + getUrl: function (server, address) { + console.log(server + 'read/' + address); + return server + 'read/' + address; } }); })(); diff --git a/webapp/app/elements/my-greeting/my-greeting.html b/webapp/app/elements/my-greeting/my-greeting.html deleted file mode 100644 index 8bc2a47..0000000 --- a/webapp/app/elements/my-greeting/my-greeting.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> -<link rel="import" href="../../bower_components/polymer/polymer.html"> - -<dom-module id="my-greeting"> - <template> - <style include="shared-styles"></style> - <style> - :host { - display: block; - } - </style> - <h2 class="page-title"><span>{{greeting}}</span></h2> - <span class="paper-font-body2">Update text to change the greeting.</span> - <!-- Listens for "input" event and sets greeting to <input>.value --> - <input class="paper-font-body2" value="{{greeting::input}}"> - </template> - - <script> - (function() { - 'use strict'; - - Polymer({ - is: 'my-greeting', - - properties: { - greeting: { - type: String, - value: 'Welcome!', - notify: true - } - } - }); - })(); - </script> - -</dom-module> diff --git a/webapp/app/elements/my-list/my-list.html b/webapp/app/elements/my-list/my-list.html deleted file mode 100644 index e4048fb..0000000 --- a/webapp/app/elements/my-list/my-list.html +++ /dev/null @@ -1,52 +0,0 @@ -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> -<link rel="import" href="../../bower_components/polymer/polymer.html"> - -<dom-module id="my-list"> - <template> - <style> - :host { - display: block; - } - </style> - <ul> - <template is="dom-repeat" items="{{items}}"> - <li><span class="paper-font-body1">{{item}}</span></li> - </template> - </ul> - </template> - - <script> - (function () { - 'use strict'; - - Polymer({ - is: 'my-list', - properties: { - items: { - type: Array, - notify: true, - } - }, - ready: function() { - this.items = [ - 'Responsive Web App boilerplate', - 'Iron Elements and Paper Elements', - 'End-to-end Build Tooling (including Vulcanize)', - 'Unit testing with Web Component Tester', - 'Routing with Page.js', - 'Offline support with the Platinum Service Worker Elements' - ]; - } - }); - })(); - </script> - -</dom-module> diff --git a/webapp/app/elements/routing.html b/webapp/app/elements/routing.html index 22e883f..2d7ff3d 100644 --- a/webapp/app/elements/routing.html +++ b/webapp/app/elements/routing.html @@ -34,6 +34,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN page('/read/:address', scrollToTop, function(data) { app.route = 'message-list'; app.params = data.params; + console.log(data); }); // add #! before urls diff --git a/webapp/app/scripts/app.js b/webapp/app/scripts/app.js index 14df9d9..e787489 100644 --- a/webapp/app/scripts/app.js +++ b/webapp/app/scripts/app.js @@ -16,9 +16,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN var app = document.querySelector('#app'); app.join = function() { - var index = 0; var result = ''; - for (index = 0; index < arguments.length; index++) { + for (var index = 0; index < arguments.length; index++) { result += arguments[index]; } return result; diff --git a/webapp/app/test/index.html b/webapp/app/test/index.html deleted file mode 100644 index 6981750..0000000 --- a/webapp/app/test/index.html +++ /dev/null @@ -1,32 +0,0 @@ -<!doctype html> -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> - -<html> - - <head> - <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> - <title>Elements Test Runner</title> - <meta charset="UTF-8"> - - <script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script> - <script src="../../bower_components/web-component-tester/browser.js"></script> - </head> - - <body> - - <script> - WCT.loadSuites(['my-greeting-basic.html', 'my-list-basic.html']); - </script> - - - </body> - -</html> diff --git a/webapp/app/test/my-greeting-basic.html b/webapp/app/test/my-greeting-basic.html deleted file mode 100644 index 8cd6022..0000000 --- a/webapp/app/test/my-greeting-basic.html +++ /dev/null @@ -1,52 +0,0 @@ -<!doctype html> -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> - -<html> -<head> - <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> - <title>my-greeting-basic</title> - - <script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script> - <script src="../../bower_components/web-component-tester/browser.js"></script> - <script src="../../bower_components/test-fixture/test-fixture-mocha.js"></script> - <link rel="import" href="../../bower_components/test-fixture/test-fixture.html"> - - <!-- Import the element to test --> - <link rel="import" href="../elements/my-greeting/my-greeting.html"> - -</head> -<body> - - <test-fixture id="basic"> - <template> - <my-greeting></my-greeting> - </template> - </test-fixture> - - <script> - - suite('my-greeting tests', function() { - var greeting, header; - - setup(function() { - greeting = fixture('basic'); - }); - - test('Welcome!', function() { - header = greeting.querySelector('h2'); - assert.equal(header.textContent, 'Welcome!'); - }); - - }); - </script> - -</body> -</html> diff --git a/webapp/app/test/my-list-basic.html b/webapp/app/test/my-list-basic.html deleted file mode 100644 index f4b9298..0000000 --- a/webapp/app/test/my-list-basic.html +++ /dev/null @@ -1,67 +0,0 @@ -<!doctype html> -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> - -<html> -<head> - <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> - <title>my-list-basic</title> - - <script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script> - <script src="../../bower_components/web-component-tester/browser.js"></script> - <script src="../../bower_components/test-fixture/test-fixture-mocha.js"></script> - <link rel="import" href="../../bower_components/test-fixture/test-fixture.html"> - - <!-- Import the element to test --> - <link rel="import" href="../elements/my-list/my-list.html"> - -</head> -<body> - - <test-fixture id="basic"> - <template> - <my-list></my-list> - </template> - </test-fixture> - - <script> - suite('my-list tests', function() { - var list, listItems; - - setup(function() { - list = fixture('basic'); - }); - - test('Item lengths should be equalled', function(done) { - // Test a property - // TODO: Fix list.items.push('Foo') causing a WeakMap exception - // Invalid value used as weak map key - list.items = [ - 'Responsive Web App boilerplate', - 'Iron Elements and Paper Elements', - 'End-to-end Build Tooling (including Vulcanize)', - 'Unit testing with Web Component Tester', - 'Routing with Page.js', - 'Offline support with the Platinum Service Worker Elements' - ]; - - // Data bindings will stamp out new DOM asynchronously - // so wait to check for updates - flush(function() { - listItems = list.querySelectorAll('li'); - assert.equal(list.items.length, listItems.length); - done(); - }); - }) - }); - </script> - -</body> -</html>