Some refactoring, added Swagger documentation
This commit is contained in:
parent
d322d09604
commit
7adf048438
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,8 @@
|
||||
# Project specific files
|
||||
*list.conf
|
||||
config.properties
|
||||
/*.db
|
||||
/application.properties
|
||||
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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<String> whitelist;
|
||||
@Resource
|
||||
private Set<String> shortlist;
|
||||
@Resource
|
||||
private Set<String> 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<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);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(JabitServerApplication.class, args);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
@ -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>
|
@ -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>
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
Loading…
Reference in New Issue
Block a user