Commit 1f7eeae6 authored by Alexander Lercher's avatar Alexander Lercher

Changed tests, using env-var to run locally

parent 09582cf4
''' This script provides information about the environment SMART runs in. '''
import os
def is_running_locally():
'''Set env var ARTICONF_LOCAL=1 to run locally.'''
server = True
try:
if str(os.environ['ARTICONF_LOCAL']) == '1':
server = False
except KeyError:
pass
return not server
\ No newline at end of file
'''Contains all networking constants for microservices to communicate to each other.''' '''Contains all networking constants for microservices to communicate to each other.'''
# set to false to run locally from env_info import is_running_locally
# TODO set by using environment variable
server = True # run locally if env var ARTICONF_LOCAL=1
server = not is_running_locally()
#region Rabbit MQ #region Rabbit MQ
if server: if server:
......
swagger: "2.0"
info:
title: RESTful API Gateway
description: This is the documentation for the RESTful API gateway.
version: "1.0.0"
consumes:
- "application/json"
produces:
- "application/json"
basePath: "/api"
# Paths supported by the server application
paths:
/secret:
get:
operationId: "routes.user.secret"
tags:
- "User"
summary: "Testpage for authentication"
description: "Should only be accessible with a valid JWT token in the 'authorization' header"
responses:
'200':
description: "OK"
'401':
description: "No or an invalid token was provided"
/tokens/{token}:
post:
operationId: "routes.user.verify"
tags:
- "User"
summary: "Verifies a user token"
description: "Verifies a user token"
parameters:
- name: "token"
in: "path"
description: "Target token that will be verified"
required: true
type: "string"
responses:
'200':
description: "Verification successful"
'401':
description: "Invalid token"
/tokens:
post:
operationId: "routes.user.authenticate"
tags:
- "User"
summary: "Authenticates user at the backend"
description: "Authenticates user at the backend creating a JWT token in the backend"
parameters:
- in: body
name: "Object"
required: true
schema:
$ref: '#/definitions/TokenRequest'
responses:
'200':
description: "Authentication successful"
schema:
$ref: "#/definitions/TokenReply"
'400':
description: "Wrong credentials"
/users/username/{username}:
delete:
operationId: "routes.user.delete"
tags:
- "User"
summary: "Deletes a user identified by the username from the database"
description: "Deletes a user identified by the username from the database"
parameters:
- name: "username"
in: "path"
description: "Username of the user to be deleted"
required: true
type: "string"
responses:
'200':
description: "Deletion succeeded"
'400':
description: "User does not exist"
/users:
get:
operationId: "routes.user.all"
tags:
- "User"
summary: "Retrieves all users from the database"
description: "Retrieves all users from the database"
responses:
'200':
description: complete user object including numeric ID
schema:
type: array
items:
$ref: "#/definitions/User"
'400':
description: wrong username or password
post:
operationId: "routes.user.add"
tags:
- "User"
summary: "Adds a new user to the database"
description: "Adds a new user to the database"
parameters:
- in: body
name: "Object"
required: true
schema:
type: object
properties:
username:
type: string
example: "username@domain.com"
password:
type: string
example: "secure_passw0rd"
responses:
'200':
description: "User was added to the database"
'400':
description: "User already exists"
/debug:
post:
operationId: "routes.debug.echo"
tags:
- "Echo"
summary: "Echo function for debugging purposes"
description: "Echoes the input back to the caller."
parameters:
- in: body
name: "Object"
required: true
schema:
type: object
responses:
'200':
description: "Successful echo of request data"
/trace:
post:
operationId: "routes.blockchain_trace.receive"
tags:
- "Blockchain Trace"
summary: "Add a new blockchain trace to SMART"
description: "Receives a new blockchain trace to store in SMART."
parameters:
- in: body
name: "BlockchainTrace"
description: "The trace to be added"
required: true
schema:
$ref: "#/definitions/BlockchainTrace"
responses:
'201':
description: "Successfully added"
'400':
description: "Invalid input"
definitions:
TokenReply:
type: "object"
required:
- token
properties:
token:
type: string
example: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXJuYW1lQGRvbWFpbi5jb20iLCJjcmVhdGVkX2F0IjoiMjAyMC0wNy0xNSAxNTo0Mzo0OC43MjQ4MjciLCJ2YWxpZF91bnRpbCI6IjIwMjAtMDctMTYgMTU6NDM6NDguNzI0ODI3In0.aR2Xe3pXj_MBS9UJKqhiq4u9M6Bv41ILPaKpA8BVzIY"
TokenRequest:
type: "object"
required:
- username
- password
properties:
username:
type: string
example: "username@domain.com"
password:
type: string
example: "secure_passw0rd"
User:
type: "object"
required:
- username
- password
- role
- created_at
- last_login
properties:
username:
type: string
example: "username@domain.com"
password:
type: string
example: "secure_passw0rd"
role:
type: string
example: "u"
created_at:
type: string
example: "2020-07-14 14:37:31.670671"
last_login:
type: string
example: "2020-07-14 14:37:31.670671"
BlockchainTrace:
type: "object"
properties:
TransactionId:
type: string
format: uuid
Timestamp:
type: "string"
format: "date-time"
ApplicationType:
type: "string"
TransactionFrom:
type: "string"
format: "uuid"
TransactionFromLatLng:
type: "string"
TransactionTo:
type: "string"
format: "uuid"
TransactionToLatLng:
type: "string"
TransferredAsset:
type: "string"
ResourceIds:
type: "string"
ResourceMd5:
type: "string"
ResourceState:
type: "string"
Metadata:
type: "string"
...@@ -16,16 +16,13 @@ logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) ...@@ -16,16 +16,13 @@ logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
################################# #################################
import connexion import connexion
from security import swagger_util from security import swagger_util
from env_info import is_running_locally
# load swagger config
app = connexion.App(__name__, specification_dir='configs/') app = connexion.App(__name__, specification_dir='configs/')
app.add_api(swagger_util.get_bundled_specs(Path("configs/swagger.yml")),
resolver = connexion.RestyResolver("cms_rest_api"))
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
def api_root(): def api_root():
return 'Endpoint of SMART RESTful API Gateway!' return 'Endpoint of SMART RESTful API Gateway!'
...@@ -37,6 +34,16 @@ except KeyError: ...@@ -37,6 +34,16 @@ except KeyError:
certificate_path = '/srv/articonf/' certificate_path = '/srv/articonf/'
context = (os.path.normpath(f'{certificate_path}/articonf1.crt'), os.path.normpath(f'{certificate_path}/articonf1.key')) # certificate and key files context = (os.path.normpath(f'{certificate_path}/articonf1.crt'), os.path.normpath(f'{certificate_path}/articonf1.key')) # certificate and key files
if is_running_locally():
# Local Mode
print("Running with local settings...")
app.add_api(swagger_util.get_bundled_specs(Path("configs/swagger_local.yml")),
resolver = connexion.RestyResolver("cms_rest_api"))
context = 'adhoc'
else:
app.add_api(swagger_util.get_bundled_specs(Path("configs/swagger.yml")),
resolver = connexion.RestyResolver("cms_rest_api"))
# start app # start app
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False, ssl_context=context) # disable reloader so only subscribed once to rabbitmq app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False, ssl_context=context) # disable reloader so only subscribed once to rabbitmq
\ No newline at end of file
# add modules folder to interpreter path # add modules folder to interpreter path
import sys import sys
import os import os
modules_paths = ['../', '../../../modules/', '../../modules'] modules_paths = ['./', '../', '../../../modules/', '../../modules']
for path in modules_paths: for path in modules_paths:
if os.path.exists(path): if os.path.exists(path):
sys.path.insert(1, path) sys.path.insert(1, path)
# add modules folder to interpreter path # add modules folder to interpreter path
import sys import sys
import os import os
modules_paths = ['../', '../../../../modules/', '../../../modules/'] modules_paths = ['./', '../', '../../../../modules/', '../../../modules/']
for path in modules_paths: for path in modules_paths:
if os.path.exists(path): if os.path.exists(path):
print(path)
sys.path.insert(1, path) sys.path.insert(1, path)
...@@ -22,6 +22,27 @@ class Test_MessageHandler(unittest.TestCase): ...@@ -22,6 +22,27 @@ class Test_MessageHandler(unittest.TestCase):
self.msg_sender = DummyMessageSender.get_instance() self.msg_sender = DummyMessageSender.get_instance()
self.handler = MessageHandler(self.repo, self.msg_sender) self.handler = MessageHandler(self.repo, self.msg_sender)
def _get_valid_message(self) -> str:
message_values = \
{ 'type': 'blockchain-transaction',
'content':
{
"ApplicationType": "string",
"Metadata": {},
"ResourceIds": "string",
"ResourceMd5": "string",
"ResourceState": "string",
"Timestamp": "2019-08-27T14:00:48.587Z",
"TransactionFrom": "string",
"TransactionFromLatLng": "string",
"TransactionId": "string",
"TransactionTo": "string",
"TransactionToLatLng": "string",
"TransferredAsset": "string"
}
}
return json.dumps(message_values)
def test_handleGeneric_emptyMessage_NotJsonError(self): def test_handleGeneric_emptyMessage_NotJsonError(self):
res = self.handler.handle_generic('') res = self.handler.handle_generic('')
self.assertEqual(self.handler.MSG_NOT_JSON, res) self.assertEqual(self.handler.MSG_NOT_JSON, res)
...@@ -60,32 +81,12 @@ class Test_MessageHandler(unittest.TestCase): ...@@ -60,32 +81,12 @@ class Test_MessageHandler(unittest.TestCase):
res = self.handler.handle_generic(message) res = self.handler.handle_generic(message)
self.assertEqual(self.handler.MSG_NOT_PROCESSED, res) self.assertEqual(self.handler.MSG_NOT_PROCESSED, res)
def _get_valid_message(self) -> str:
message_values = \
{ 'type': 'blockchain-transaction',
'content':
{
"ApplicationType": "string",
"Metadata": {},
"ResourceIds": "string",
"ResourceMd5": "string",
"ResourceState": "string",
"Timestamp": "2019-08-27T14:00:48.587Z",
"TransactionFrom": "string",
"TransactionFromLatLng": "string",
"TransactionId": "string",
"TransactionTo": "string",
"TransactionToLatLng": "string",
"TransferredAsset": "string"
}
}
return json.dumps(message_values)
def test_handleGeneric_correctTraceContent_ProcessedResult(self): def test_handleGeneric_correctTraceContent_ProcessedResult(self):
res = self.handler.handle_generic(self._get_valid_message()) res = self.handler.handle_generic(self._get_valid_message())
self.assertEqual(self.handler.MSG_TRACE_PROCESSED, res) self.assertEqual(self.handler.MSG_TRACE_PROCESSED, res)
def test_handleGeneric_correctTraceContent_AddedToRepo(self): def test_handleGeneric_correctTraceContent_AddedToRepo(self):
# TODO repo should contain processed datapoint
msg = self._get_valid_message() msg = self._get_valid_message()
_ = self.handler.handle_generic(msg) _ = self.handler.handle_generic(msg)
...@@ -93,6 +94,7 @@ class Test_MessageHandler(unittest.TestCase): ...@@ -93,6 +94,7 @@ class Test_MessageHandler(unittest.TestCase):
self.assertEqual(trace, self.repo.last_trace) self.assertEqual(trace, self.repo.last_trace)
def test_handleGeneric_correctTraceContent_NotificationSentCorrectly(self): def test_handleGeneric_correctTraceContent_NotificationSentCorrectly(self):
# TODO message queue should contain new message with datapoint as content
msg = self._get_valid_message() msg = self._get_valid_message()
_ = self.handler.handle_generic(msg) _ = self.handler.handle_generic(msg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment