Commit 76a26396 authored by Alexander Lercher's avatar Alexander Lercher

[RoleStage] Added use-case and table to endpoints and clustering #19

parent 553c2da8
...@@ -17,41 +17,56 @@ paths: ...@@ -17,41 +17,56 @@ paths:
description: "Successful echo of request data" description: "Successful echo of request data"
#region Layers #region Layers
/layers: /{use_case}/layers:
post: get:
operationId: "routes.layers.post" operationId: "routes.layers.get_by_use_case"
security: security:
- JwtRegular: [] - JwtRegular: []
tags: tags:
- "Layers" - "Layers"
summary: "Add a new layer [TODO: or overwrite an existing one]" summary: "Get all layer data for one use case"
parameters: parameters:
- in: body - name: "use_case"
name: "layer" in: "path"
description: "The layer data to be added" description: "Name of the use-case"
required: true required: true
schema: type: "string"
$ref: "#/definitions/Layer"
responses: responses:
'201': '200':
description: "Successful operation" description: "Successful operation"
'400': schema:
description: "Invalid input" $ref: "#/definitions/LayerCollection"
'404':
description: "No content for use-case"
/{use_case}/{use_case_table}/layers:
get: get:
operationId: "routes.layers.get" operationId: "routes.layers.get_by_table"
security: security:
- JwtRegular: [] - JwtRegular: []
tags: tags:
- "Layers" - "Layers"
summary: "Get all layer data" summary: "Get all layer data for one use case"
parameters: [] parameters:
- name: "use_case"
in: "path"
description: "Name of the use-case"
required: true
type: "string"
- name: "use_case_table"
in: "path"
description: "Name of the use-case table"
required: true
type: "string"
responses: responses:
'200': '200':
description: "Successful operation" description: "Successful operation"
schema: schema:
$ref: "#/definitions/LayerCollection" $ref: "#/definitions/LayerCollection"
'404':
description: "No content for use-case"
/layers/{name}: /{use_case}/{use_case_table}/layers/{name}:
get: get:
operationId: "routes.layers.get_by_name" operationId: "routes.layers.get_by_name"
security: security:
...@@ -60,6 +75,16 @@ paths: ...@@ -60,6 +75,16 @@ paths:
- "Layers" - "Layers"
summary: "Get single layer data" summary: "Get single layer data"
parameters: parameters:
- name: "use_case"
in: "path"
description: "Name of the use-case"
required: true
type: "string"
- name: "use_case_table"
in: "path"
description: "Name of the use-case table"
required: true
type: "string"
- name: "name" - name: "name"
in: "path" in: "path"
description: "Name of the requested layer" description: "Name of the requested layer"
...@@ -73,7 +98,7 @@ paths: ...@@ -73,7 +98,7 @@ paths:
'404': '404':
description: "Layer not found" description: "Layer not found"
/layers/{name}/nodes: /{use_case}/{use_case_table}/layers/{name}/nodes:
get: get:
operationId: "routes.layers.get_nodes" operationId: "routes.layers.get_nodes"
security: security:
...@@ -81,7 +106,17 @@ paths: ...@@ -81,7 +106,17 @@ paths:
tags: tags:
- "Layers" - "Layers"
summary: "Get all individual nodes for the layer" summary: "Get all individual nodes for the layer"
parameters: parameters:
- name: "use_case"
in: "path"
description: "Name of the use-case"
required: true
type: "string"
- name: "use_case_table"
in: "path"
description: "Name of the use-case table"
required: true
type: "string"
- name: "name" - name: "name"
in: "path" in: "path"
description: "Name of the layer" description: "Name of the layer"
...@@ -94,32 +129,8 @@ paths: ...@@ -94,32 +129,8 @@ paths:
$ref: "#/definitions/NodeCollection" $ref: "#/definitions/NodeCollection"
'404': '404':
description: "Layer not found" description: "Layer not found"
post:
operationId: "routes.layers.post_nodes"
security:
- JwtRegular: []
tags:
- "Layers"
summary: "Adds a single or multiple nodes to the layer"
parameters:
- name: "name"
in: "path"
description: "Name of the layer"
required: true
type: "string"
- name: "node"
in: body
description: "The node(s) to be added"
required: true
schema:
$ref: "#/definitions/NodeCollection"
responses:
'201':
description: "Successful operation"
'400':
description: "Invalid input"
/layers/{name}/clusters: /{use_case}/{use_case_table}/layers/{name}/clusters:
get: get:
operationId: "routes.clustersets.get_by_name" operationId: "routes.clustersets.get_by_name"
security: security:
...@@ -128,6 +139,16 @@ paths: ...@@ -128,6 +139,16 @@ paths:
- "Layers" - "Layers"
summary: "Get all clusters for the layer" summary: "Get all clusters for the layer"
parameters: parameters:
- name: "use_case"
in: "path"
description: "Name of the use-case"
required: true
type: "string"
- name: "use_case_table"
in: "path"
description: "Name of the use-case table"
required: true
type: "string"
- name: "name" - name: "name"
in: "path" in: "path"
description: "Name of the layer" description: "Name of the layer"
...@@ -141,7 +162,7 @@ paths: ...@@ -141,7 +162,7 @@ paths:
'404': '404':
description: "Layer not found" description: "Layer not found"
/layers/{name}/timeslices: /{use_case}/{use_case_table}/layers/{name}/timeslices:
get: get:
operationId: "routes.timeslices.get_by_name" operationId: "routes.timeslices.get_by_name"
security: security:
...@@ -150,6 +171,16 @@ paths: ...@@ -150,6 +171,16 @@ paths:
- "Layers" - "Layers"
summary: "Get all timeslices for the layer" summary: "Get all timeslices for the layer"
parameters: parameters:
- name: "use_case"
in: "path"
description: "Name of the use-case"
required: true
type: "string"
- name: "use_case_table"
in: "path"
description: "Name of the use-case table"
required: true
type: "string"
- name: "name" - name: "name"
in: "path" in: "path"
description: "Name of the layer" description: "Name of the layer"
...@@ -165,23 +196,7 @@ paths: ...@@ -165,23 +196,7 @@ paths:
#endregion #endregion
#region Function Calls #region Similarity
/rfc/run:
post:
operationId: "routes.functions.run_agi_clustering_and_graph_creation"
security:
- JwtRegular: []
tags:
- "Remote function calls"
summary: "Insert locations from AGI, create clusters for starting time and location layers, create graphs for the location clusters"
parameters: []
responses:
'204':
description: "Successful operation"
#endregion
################################################################################
/connectedClusters: /connectedClusters:
get: get:
operationId: "routes.connClusters.get_conn_clusters" operationId: "routes.connClusters.get_conn_clusters"
...@@ -239,11 +254,14 @@ paths: ...@@ -239,11 +254,14 @@ paths:
schema: schema:
$ref: "#/definitions/ClusterRunArray" $ref: "#/definitions/ClusterRunArray"
#endregion Similarity
definitions: definitions:
Cluster: Cluster:
type: object type: object
properties: properties:
use_case:
type: string
layer_name: layer_name:
type: string type: string
cluster_label: cluster_label:
...@@ -299,6 +317,8 @@ definitions: ...@@ -299,6 +317,8 @@ definitions:
time: time:
type: object type: object
example: "(2020, 52)" example: "(2020, 52)"
use_case:
type: string
layer_name: layer_name:
type: string type: string
clusters: clusters:
...@@ -320,10 +340,6 @@ definitions: ...@@ -320,10 +340,6 @@ definitions:
items: items:
$ref: "#/definitions/TimeSlice" $ref: "#/definitions/TimeSlice"
##################################################################
ConnectedDict: ConnectedDict:
type: array type: array
items: items:
......
...@@ -7,13 +7,18 @@ class Cluster: ...@@ -7,13 +7,18 @@ class Cluster:
''' '''
A cluster for an arbitrary layer containing some nodes. A cluster for an arbitrary layer containing some nodes.
:param use_case: The use-case of the layer
:param use_case_table: The use-case table of the layer
:param layer_name: The name of the layer in which the cluster is located :param layer_name: The name of the layer in which the cluster is located
:param cluster_label: The label of the cluster unique for the layer :param cluster_label: The label of the cluster unique for the layer
:param nodes: The individual nodes of the cluster :param nodes: The individual nodes of the cluster
''' '''
def __init__(self, layer_name: str = None, cluster_label: int = None, nodes: List[Dict] = None, def __init__(self, use_case: str = None, use_case_table: str = None, layer_name: str = None,
cluster_label: int = None, nodes: List[Dict] = None,
cluster_dict: Dict = None, from_db=False): cluster_dict: Dict = None, from_db=False):
self.use_case = use_case
self.use_case_table = use_case_table
self.layer_name = layer_name self.layer_name = layer_name
self.cluster_label = cluster_label self.cluster_label = cluster_label
self.nodes = nodes self.nodes = nodes
...@@ -23,12 +28,16 @@ class Cluster: ...@@ -23,12 +28,16 @@ class Cluster:
def to_serializable_dict(self, for_db=False) -> Dict: def to_serializable_dict(self, for_db=False) -> Dict:
return { return {
"use_case": self.use_case,
"use_case_table": self.use_case_table,
"layer_name": self.layer_name, "layer_name": self.layer_name,
"cluster_label": self.cluster_label, "cluster_label": self.cluster_label,
"nodes": json.dumps(self.nodes) if for_db else self.nodes "nodes": json.dumps(self.nodes) if for_db else self.nodes
} }
def from_serializable_dict(self, cluster_dict: Dict, from_db=False): def from_serializable_dict(self, cluster_dict: Dict, from_db=False):
self.use_case = cluster_dict["use_case"]
self.use_case_table = cluster_dict["use_case_table"]
self.layer_name = cluster_dict["layer_name"] self.layer_name = cluster_dict["layer_name"]
self.cluster_label = cluster_dict["cluster_label"] self.cluster_label = cluster_dict["cluster_label"]
self.nodes = json.loads(cluster_dict["nodes"]) \ self.nodes = json.loads(cluster_dict["nodes"]) \
......
...@@ -18,6 +18,7 @@ class Layer: ...@@ -18,6 +18,7 @@ class Layer:
"layer_name": self.layer_name, "layer_name": self.layer_name,
"properties": self.properties, "properties": self.properties,
"use_case": self.use_case, "use_case": self.use_case,
"use_case_table": self.use_case_table,
"total_properties": self.total_properties, "total_properties": self.total_properties,
} }
...@@ -28,12 +29,14 @@ class Layer: ...@@ -28,12 +29,14 @@ class Layer:
layer.properties = layer_info["cluster_properties"] layer.properties = layer_info["cluster_properties"]
layer.total_properties = layer_info["properties"] layer.total_properties = layer_info["properties"]
layer.use_case = layer_info["use_case"] layer.use_case = layer_info["use_case"]
layer.use_case_table = layer_info["table"]
return layer return layer
def from_serializable_dict(self, layer_info: Dict, from_db=False): def from_serializable_dict(self, layer_info: Dict, from_db=False):
self.layer_name = layer_info['layer_name'] self.layer_name = layer_info['layer_name']
self.properties = layer_info['properties'] self.properties = layer_info['properties']
self.use_case = layer_info["use_case"] if "use_case" in layer_info.keys() else None self.use_case = layer_info["use_case"]
self.use_case_table = layer_info["use_case_table"]
self.total_properties = layer_info["total_properties"] if "total_properties"in layer_info.keys() else None self.total_properties = layer_info["total_properties"] if "total_properties"in layer_info.keys() else None
def __repr__(self): def __repr__(self):
......
...@@ -12,9 +12,11 @@ class TimeSlice: ...@@ -12,9 +12,11 @@ class TimeSlice:
:param layer_name: The name of the layer the nodes belong to :param layer_name: The name of the layer the nodes belong to
''' '''
def __init__(self, time: Any, layer_name: str, def __init__(self, time: Any = None, use_case: str = None, use_case_table: str = None, layer_name: str = None,
time_slice_dict: Dict = None, from_db = False): time_slice_dict: Dict = None, from_db = False):
self.time = str(time) self.time = str(time)
self.use_case = use_case
self.use_case_table = use_case_table
self.layer_name = layer_name self.layer_name = layer_name
self.clusters: Dict[str, List[Node]] = {} self.clusters: Dict[str, List[Node]] = {}
...@@ -47,12 +49,16 @@ class TimeSlice: ...@@ -47,12 +49,16 @@ class TimeSlice:
def to_serializable_dict(self, for_db=False) -> Dict: def to_serializable_dict(self, for_db=False) -> Dict:
return { return {
"time": self.time, "time": self.time,
"use_case": self.use_case,
"use_case_table": self.use_case_table,
'layer_name': self.layer_name, 'layer_name': self.layer_name,
"clusters": json.dumps(self.clusters) if for_db else self.clusters "clusters": json.dumps(self.clusters) if for_db else self.clusters
} }
def from_serializable_dict(self, dict: Dict, from_db=False): def from_serializable_dict(self, dict: Dict, from_db=False):
self.time = dict["time"] self.time = dict["time"]
self.use_case = dict["use_case"]
self.use_case_tables = dict["use_case_tables"]
self.layer_name = dict['layer_name'] self.layer_name = dict['layer_name']
self.clusters = json.loads(dict['clusters']) if from_db else dict['clusters'] self.clusters = json.loads(dict['clusters']) if from_db else dict['clusters']
......
...@@ -7,6 +7,9 @@ from db.entities import * ...@@ -7,6 +7,9 @@ from db.entities import *
# from processing.similarityFiles.miscFunctions import * # from processing.similarityFiles.miscFunctions import *
from typing import List from typing import List
import logging
LOGGER = logging.getLogger(__name__)
class Repository(MongoRepositoryBase): class Repository(MongoRepositoryBase):
'''This is a repository for MongoDb.''' '''This is a repository for MongoDb.'''
...@@ -14,7 +17,7 @@ class Repository(MongoRepositoryBase): ...@@ -14,7 +17,7 @@ class Repository(MongoRepositoryBase):
def __init__(self): def __init__(self):
super().__init__(netconst.ROLESTAGE_DISCOVERY_DB_HOSTNAME, super().__init__(netconst.ROLESTAGE_DISCOVERY_DB_HOSTNAME,
netconst.ROLESTAGE_DISCOVERY_DB_PORT, netconst.ROLESTAGE_DISCOVERY_DB_PORT,
'roleStageDb') 'roleStageDb-testing')
self._layer_collection = 'layers' self._layer_collection = 'layers'
self._layer_nodes_collection = 'layer_nodes' self._layer_nodes_collection = 'layer_nodes'
...@@ -30,14 +33,26 @@ class Repository(MongoRepositoryBase): ...@@ -30,14 +33,26 @@ class Repository(MongoRepositoryBase):
super().insert_entry(self._layer_collection, layer.to_serializable_dict()) super().insert_entry(self._layer_collection, layer.to_serializable_dict())
def get_layers(self) -> List[Layer]: def get_layers(self) -> List[Layer]:
'''Retrieves all layers from the db, independent of use-case.'''
entries = super().get_entries(self._layer_collection) entries = super().get_entries(self._layer_collection)
return [Layer(e) for e in entries] return [Layer(e) for e in entries]
def get_layer(self, layer_name) -> Layer: def get_layers_for_use_case(self, use_case: str) -> Layer:
entries = super().get_entries(self._layer_collection, selection={'layer_name': layer_name}) entries = super().get_entries(self._layer_collection, selection={'use_case': use_case})
return [Layer(e) for e in entries]
def get_layers_for_table(self, use_case: str, use_case_table: str) -> Layer:
entries = super().get_entries(self._layer_collection, selection={'use_case': use_case, 'use_case_table': use_case_table})
return [Layer(e) for e in entries]
def get_layer_by_name(self, use_case:str, use_case_table:str, layer_name:str) -> Layer:
'''Returns a singe layer for use-case and layer-name.'''
entries = super().get_entries(self._layer_collection, selection={'use_case': use_case, 'use_case_table': use_case_table, 'layer_name': layer_name})
entries = [Layer(e) for e in entries] entries = [Layer(e) for e in entries]
if entries is not None and len(entries) > 0: if entries is not None and len(entries) > 0:
if len(entries) > 1:
LOGGER.error(f"Layer Key {use_case}, {layer_name} is not unique.")
return entries[0] return entries[0]
else: else:
return None return None
...@@ -45,27 +60,22 @@ class Repository(MongoRepositoryBase): ...@@ -45,27 +60,22 @@ class Repository(MongoRepositoryBase):
def delete_all_layers(self): def delete_all_layers(self):
super().drop_collection(self._layer_collection) super().drop_collection(self._layer_collection)
#endregion Layers
#region Layer Nodes
def delete_all_nodes(self): def delete_all_nodes(self):
super().drop_collection(self._layer_nodes_collection) super().drop_collection(self._layer_nodes_collection)
def get_layer_for_use_case(self, layer_name: str, use_case: str) -> Layer:
entries = super().get_entries(self._layer_collection, selection={'layer_name': layer_name, 'use_case': use_case})
entries = [Layer(e) for e in entries]
if entries is not None and len(entries) > 0:
return entries[0]
else:
return None
def add_layer_node(self, node: dict): def add_layer_node(self, node: dict):
super().insert_entry(self._layer_nodes_collection, node) super().insert_entry(self._layer_nodes_collection, node)
def add_layer_nodes(self, nodes:List[dict]): def add_layer_nodes(self, nodes:List[dict]):
super().insert_many(self._layer_nodes_collection, nodes) super().insert_many(self._layer_nodes_collection, nodes)
def get_layer_nodes(self, layer_name: str) -> dict: def get_layer_nodes(self, use_case: str, use_case_table: str, layer_name: str) -> dict:
'''Returns all nodes for the layer.''' '''Returns all nodes for the use-case and layer.'''
entries = super().get_entries(self._layer_nodes_collection, selection={'layer_name': layer_name}, projection={'_id': 0}) entries = super().get_entries(self._layer_nodes_collection, selection={'use_case': use_case, 'use_case_table': use_case_table, 'layer_name': layer_name}, projection={'_id': 0})
return [e for e in entries] return [e for e in entries]
#endregion #endregion
...@@ -75,8 +85,8 @@ class Repository(MongoRepositoryBase): ...@@ -75,8 +85,8 @@ class Repository(MongoRepositoryBase):
cluster_dicts = [c.to_serializable_dict(for_db=True) for c in clusters] cluster_dicts = [c.to_serializable_dict(for_db=True) for c in clusters]
super().insert_many(self._clusters_collection, cluster_dicts) super().insert_many(self._clusters_collection, cluster_dicts)
def get_clusters_for_layer(self, layer_name: str) -> List[Cluster]: def get_clusters_for_layer(self, use_case: str, use_case_table: str, layer_name: str) -> List[Cluster]:
entries = super().get_entries(self._clusters_collection, selection={'layer_name': layer_name}, projection={'_id': 0}) entries = super().get_entries(self._clusters_collection, selection={'use_case': use_case, 'use_case_table': use_case_table, 'layer_name': layer_name}, projection={'_id': 0})
return [Cluster(cluster_dict=e, from_db=True) for e in entries] return [Cluster(cluster_dict=e, from_db=True) for e in entries]
def delete_all_clusters(self): def delete_all_clusters(self):
...@@ -93,10 +103,10 @@ class Repository(MongoRepositoryBase): ...@@ -93,10 +103,10 @@ class Repository(MongoRepositoryBase):
entries = super().get_entries(self._time_slice_collection) entries = super().get_entries(self._time_slice_collection)
return [TimeSlice(None, None, time_slice_dict=e, from_db=True) for e in entries] return [TimeSlice(None, None, time_slice_dict=e, from_db=True) for e in entries]
def get_time_slices_by_name(self, layer_name) -> List[TimeSlice]: def get_time_slices_by_name(self, use_case: str, use_case_table: str, layer_name: str) -> List[TimeSlice]:
'''Returns all time slices with the given layer_name.''' '''Returns all time slices with the given layer_name.'''
entries = super().get_entries(self._time_slice_collection, selection={'layer_name': layer_name}) entries = super().get_entries(self._time_slice_collection, selection={'use_case': use_case, 'use_case_table': use_case_table, 'layer_name': layer_name})
return [TimeSlice(None, None, time_slice_dict=e, from_db=True) for e in entries] return [TimeSlice(time_slice_dict=e, from_db=True) for e in entries]
def remove_all_time_slices(self): def remove_all_time_slices(self):
super().drop_collection(self._time_slice_collection) super().drop_collection(self._time_slice_collection)
......
...@@ -7,10 +7,11 @@ from typing import List, Dict ...@@ -7,10 +7,11 @@ from typing import List, Dict
import requests import requests
import json import json
def _fetch_layers(use_case: str) -> List[Layer]:
def _fetch_use_cases() -> List[str]:
jwt = TokenManager.getInstance().getToken() jwt = TokenManager.getInstance().getToken()
url = f'https://{network_constants.BUSINESS_LOGIC_HOSTNAME}:{network_constants.BUSINESS_LOGIC_REST_PORT}/api/use-cases/{use_case}/layers' url = f'https://{network_constants.BUSINESS_LOGIC_HOSTNAME}:{network_constants.BUSINESS_LOGIC_REST_PORT}/api/use-cases'
response = requests.get( response = requests.get(
url, url,
...@@ -20,21 +21,17 @@ def _fetch_layers(use_case: str) -> List[Layer]: ...@@ -20,21 +21,17 @@ def _fetch_layers(use_case: str) -> List[Layer]:
) )
if response.status_code != 200: if response.status_code != 200:
raise ConnectionError(f"Could not fetch layers for {use_case} from business-logic microservice, statuscode: {response.status_code}!") raise ConnectionError(f"Could not fetch use-cases from business-logic microservice, statuscode: {response.status_code}!")
data = json.loads(response.text) data = json.loads(response.text)
layers = [] return [row["name"] for row in data]
for row in data:
layers.append(Layer.from_business_logic_dict(row))
return layers
def _fetch_nodes(use_case: str, layer: Layer) -> List[Dict]: def _fetch_tables(use_case: str) -> List[str]:
jwt = TokenManager.getInstance().getToken() jwt = TokenManager.getInstance().getToken()
url = f'https://{network_constants.SEMANTIC_LINKING_HOSTNAME}:{network_constants.SEMANTIC_LINKING_REST_PORT}/api/use-cases/{use_case}/layers/{layer.layer_name}/nodes' url = f'https://{network_constants.BUSINESS_LOGIC_HOSTNAME}:{network_constants.BUSINESS_LOGIC_REST_PORT}/api/use-cases/{use_case}/tables'
response = requests.get( response = requests.get(
url, url,
...@@ -44,21 +41,17 @@ def _fetch_nodes(use_case: str, layer: Layer) -> List[Dict]: ...@@ -44,21 +41,17 @@ def _fetch_nodes(use_case: str, layer: Layer) -> List[Dict]:
) )
if response.status_code != 200: if response.status_code != 200:
raise ConnectionError(f"Could not fetch nodes for {use_case}/{layer.layer_name} from semantic-linking microservice, statuscode: {response.status_code}!") raise ConnectionError(f"Could not fetch tables for {use_case} from business-logic microservice, statuscode: {response.status_code}!")
data = json.loads(response.text) data = json.loads(response.text)
nodes = [] return [row["name"] for row in data]
for row in data:
nodes.append(row)
return nodes
def _fetch_use_cases() -> List[str]: def _fetch_layers(use_case: str, table: str) -> List[Layer]:
jwt = TokenManager.getInstance().getToken() jwt = TokenManager.getInstance().getToken()
url = f'https://{network_constants.BUSINESS_LOGIC_HOSTNAME}:{network_constants.BUSINESS_LOGIC_REST_PORT}/api/use-cases' url = f'https://{network_constants.BUSINESS_LOGIC_HOSTNAME}:{network_constants.BUSINESS_LOGIC_REST_PORT}/api/use-cases/{use_case}/tables/{table}/layers'
response = requests.get( response = requests.get(
url, url,
...@@ -68,14 +61,33 @@ def _fetch_use_cases() -> List[str]: ...@@ -68,14 +61,33 @@ def _fetch_use_cases() -> List[str]:
) )
if response.status_code != 200: if response.status_code != 200:
raise ConnectionError(f"Could not fetch use-cases from business-logic microservice, statuscode: {response.status_code}!") raise ConnectionError(f"Could not fetch layers for {use_case}//{table} from business-logic microservice, statuscode: {response.status_code}!")
data = json.loads(response.text) data = json.loads(response.text)
return [Layer.from_business_logic_dict(row) for row in data]
def _fetch_nodes(use_case: str, table: str, layer_name: str) -> List[Dict]:
jwt = TokenManager.getInstance().getToken()
url = f'https://{network_constants.SEMANTIC_LINKING_HOSTNAME}:{network_constants.SEMANTIC_LINKING_REST_PORT}/api/use-cases/{use_case}/tables/{table}/layers/{layer_name}/nodes'
response = requests.get(
url,
verify = False,
proxies = { "http":None, "https":None },
headers = {"Authorization": f"Bearer {jwt}"}
)
if response.status_code != 200:
raise ConnectionError(f"Could not fetch nodes for {use_case}//{table}//{layer_name} from semantic-linking microservice, statuscode: {response.status_code}!")
return response.json()
return [row["name"] for row in data]
def fetch_nodes_from_semantic_linking(): def fetch_nodes_from_semantic_linking():
# prune DB '''Empties the db and inserts layers and nodes from BusinessLogic and SemanticLinking'''
repository = Repository() repository = Repository()
repository.delete_all_layers() repository.delete_all_layers()
repository.delete_all_nodes() repository.delete_all_nodes()
...@@ -83,21 +95,31 @@ def fetch_nodes_from_semantic_linking(): ...@@ -83,21 +95,31 @@ def fetch_nodes_from_semantic_linking():
use_cases = _fetch_use_cases() use_cases = _fetch_use_cases()
for use_case in use_cases: for use_case in use_cases:
print(f"Fetching for use-case {use_case}") print(f"Fetching for use-case {use_case}")
layers = _fetch_layers(use_case)
tables = _fetch_tables(use_case)
for layer in layers: for table in tables:
try:
print(f"Fetching nodes for layer {layer.layer_name}") layers = _fetch_layers(use_case, table)
# check if layer already exists in DB, add it if not for layer in layers:
reference_layer = repository.get_layer_for_use_case(layer.layer_name, use_case)
if reference_layer == None: try:
repository.add_layer(layer) print(f"Fetching nodes for layer {use_case}//{table}//{layer.layer_name}.")
# check if layer already exists in DB, add it if not
nodes = _fetch_nodes(use_case, layer) reference_layer = repository.get_layer_by_name(use_case, table, layer.layer_name)
if reference_layer == None:
for node in nodes: repository.add_layer(layer)
repository.add_layer_node(node) else:
except ConnectionError as e: raise Exception(f"Layer should be unique, but was not: {reference_layer}")
print(str(e))
continue nodes = _fetch_nodes(use_case, table, layer.layer_name)
for node in nodes:
node['use_case_table'] = node['table']
del node['table']
for node in nodes:
repository.add_layer_node(node)
except ConnectionError as e:
print(str(e))
continue
\ No newline at end of file
...@@ -4,8 +4,8 @@ from db.entities import ClusterSet ...@@ -4,8 +4,8 @@ from db.entities import ClusterSet
repo = Repository() repo = Repository()
def get_by_name(name): def get_by_name(use_case, use_case_table, name):
res = repo.get_clusters_for_layer(name) res = repo.get_clusters_for_layer(use_case, use_case_table, name)
if res is None or len(res) == 0: if res is None or len(res) == 0:
return Response(status=404) return Response(status=404)
else: else:
......
...@@ -19,11 +19,22 @@ def _insert_layer(layer_data: dict): ...@@ -19,11 +19,22 @@ def _insert_layer(layer_data: dict):
repo.add_layer(Layer(layer_data)) repo.add_layer(Layer(layer_data))
def get(): def get_by_use_case(use_case):
return [l.to_serializable_dict() for l in repo.get_layers()] res = repo.get_layers_for_use_case(use_case)
if len(res) > 0:
return [l.to_serializable_dict() for l in res]
else:
return Response(status=404)
def get_by_table(use_case, use_case_table):
res = repo.get_layers_for_table(use_case, use_case_table)
if len(res) > 0:
return [l.to_serializable_dict() for l in res]
else:
return Response(status=404)
def get_by_name(name): def get_by_name(use_case, use_case_table, name):
res = repo.get_layer(name) res = repo.get_layer_by_name(use_case, use_case_table, name)
if res is not None: if res is not None:
return res.to_serializable_dict() return res.to_serializable_dict()
else: else:
...@@ -32,8 +43,8 @@ def get_by_name(name): ...@@ -32,8 +43,8 @@ def get_by_name(name):
#endregion #endregion
#region nodes #region nodes
def get_nodes(name): def get_nodes(use_case, use_case_table, name):
res = repo.get_layer_nodes(name) res = repo.get_layer_nodes(use_case, use_case_table, name)
# print(res) # print(res)
return res return res
......
...@@ -4,8 +4,8 @@ from db.entities import TimeSlice ...@@ -4,8 +4,8 @@ from db.entities import TimeSlice
repo = Repository() repo = Repository()
def get_by_name(name): def get_by_name(use_case, use_case_table, name):
res = repo.get_time_slices_by_name(name) res = repo.get_time_slices_by_name(use_case, use_case_table, name)
if res is not None and len(res) != 0: if res is not None and len(res) != 0:
return [e.to_serializable_dict() for e in res] return [e.to_serializable_dict() for e in res]
......
...@@ -19,7 +19,7 @@ def run_generic_clustering(): ...@@ -19,7 +19,7 @@ def run_generic_clustering():
all_layers:List[Layer] = repo.get_layers() all_layers:List[Layer] = repo.get_layers()
for layer in all_layers: for layer in all_layers:
print(f"Clustering {layer.layer_name}") print(f"Clustering {layer.use_case}, {layer.layer_name}.")
if layer.properties is None or len(layer.properties) == 0: if layer.properties is None or len(layer.properties) == 0:
print("skipping") print("skipping")
...@@ -33,7 +33,7 @@ def run_generic_clustering(): ...@@ -33,7 +33,7 @@ def run_generic_clustering():
def run_clustering_for_layer(layer: Layer) -> List[Cluster]: def run_clustering_for_layer(layer: Layer) -> List[Cluster]:
nodes = repo.get_layer_nodes(layer.layer_name) nodes = repo.get_layer_nodes(layer.use_case, layer.layer_name)
clusterer = Clusterer() clusterer = Clusterer()
res = clusterer.cluster_dataset( res = clusterer.cluster_dataset(
...@@ -41,7 +41,7 @@ def run_clustering_for_layer(layer: Layer) -> List[Cluster]: ...@@ -41,7 +41,7 @@ def run_clustering_for_layer(layer: Layer) -> List[Cluster]:
layer.properties layer.properties
) )
return [Cluster(layer.layer_name, key, value) for key, value in res.items()] return [Cluster(layer.use_case, layer.layer.layer_name, key, value) for key, value in res.items()]
def store_generic_clusters(clusters: List[Cluster]): def store_generic_clusters(clusters: List[Cluster]):
......
...@@ -7,8 +7,7 @@ if os.path.exists(modules_path): ...@@ -7,8 +7,7 @@ if os.path.exists(modules_path):
import json import json
from datetime import datetime, date from datetime import datetime, date
from db.repository import Repository from db.repository import Repository
from db.entities.timeslice import TimeSlice from db.entities import ClusterSet, Cluster, Layer, TimeSlice
from db.entities import ClusterSet, Cluster
from typing import Tuple, Dict, Any, List from typing import Tuple, Dict, Any, List
TimeSliceKey = Tuple[int, int] TimeSliceKey = Tuple[int, int]
...@@ -20,7 +19,7 @@ def convert_to_time_slice_key(timestamp: str) -> TimeSliceKey: ...@@ -20,7 +19,7 @@ def convert_to_time_slice_key(timestamp: str) -> TimeSliceKey:
return (y, w) return (y, w)
def split_clusterset_by_time(layer_name: str, clusters: List[Cluster]) -> Dict[TimeSliceKey, TimeSlice]: def split_clusterset_by_time(layer: Layer, clusters: List[Cluster]) -> Dict[TimeSliceKey, TimeSlice]:
''' '''
Distributes all nodes in clusters of a single layer into individual time slices based on their timestamps. Distributes all nodes in clusters of a single layer into individual time slices based on their timestamps.
If a node spans over multiple slices it will be added to all of them. If a node spans over multiple slices it will be added to all of them.
...@@ -43,7 +42,7 @@ def split_clusterset_by_time(layer_name: str, clusters: List[Cluster]) -> Dict[T ...@@ -43,7 +42,7 @@ def split_clusterset_by_time(layer_name: str, clusters: List[Cluster]) -> Dict[T
for time_key in time_keys: for time_key in time_keys:
if time_key not in time_slices: if time_key not in time_slices:
time_slices[time_key] = TimeSlice(time_key, layer_name) time_slices[time_key] = TimeSlice(time_key, layer.use_case, layer.layer_name)
time_slices[time_key].add_node_to_cluster(cluster_no.cluster_label, node) time_slices[time_key].add_node_to_cluster(cluster_no.cluster_label, node)
...@@ -58,14 +57,15 @@ if __name__ == "__main__": ...@@ -58,14 +57,15 @@ if __name__ == "__main__":
layers = repo.get_layers() layers = repo.get_layers()
for layer in layers: for layer in layers:
layer_name = layer.layer_name layer_name = layer.layer_name
print(f"Working on {layer_name}") use_case = layer.use_case
print(f"Working on {use_case}, {layer_name}.")
clusters_for_layer = repo.get_clusters_for_layer(layer_name) clusters_for_layer = repo.get_clusters_for_layer(use_case, layer_name)
# if no clusters were generated use one large cluster instead of skipping the layer # if no clusters were generated use one large cluster instead of skipping the layer
if clusters_for_layer is None or len(clusters_for_layer) == 0: if clusters_for_layer is None or len(clusters_for_layer) == 0:
clusters_for_layer = [Cluster(layer_name, -1, repo.get_layer_nodes(layer_name))] clusters_for_layer = [Cluster(use_case, layer_name, -1, repo.get_layer_nodes(layer_name))]
time_slices = split_clusterset_by_time(layer_name, clusters_for_layer) time_slices = split_clusterset_by_time(layer, clusters_for_layer)
for k,v in time_slices.items(): for k,v in time_slices.items():
repo.add_time_slice(v) repo.add_time_slice(v)
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