diff --git a/hackfest/commands.txt b/hackfest/commands.txt
index dbc72991b251ed9b54c42b627e9d1399884f7075..c34c6acc112e3d5dee47752967b60bab32556c94 100644
--- a/hackfest/commands.txt
+++ b/hackfest/commands.txt
@@ -1,21 +1,31 @@
-This is a quick guide for having fast access to the commands
-
-
+This is a quick guide for having fast access to the commands.
 
 ################################################################################
-# Preparation (already done):
+# Prepare environment
 ################################################################################
-$ cd ~/tfs-ctrl/hackfest
-$ pip install pyang
-$ pip install git+https://github.com/robshakir/pyangbind.git
-$ pip install netconf
-$ sudo apt-get install -y graphviz openjdk-11-jre
 
-# Download plantuml.7997.jar from http://sourceforge.net/projects/plantuml/files/plantuml.7997.jar/download
+# (done) Create PyEnv virtual environment
+cd ~/tfs-ctrl
+pyenv virtualenv 3.9.13 tfs
+pyenv local 3.9.13/envs/tfs
+./install_requirements.sh
+
+# (done) Install Python dependencies
+pip install pyang
+pip install git+https://github.com/robshakir/pyangbind.git
+pip install netconf
+
+# (done) Install PlantUML
+# (done) Install dependencies to run PlantUML
+sudo apt-get install -y graphviz openjdk-11-jre
+
+# (done) Download plantuml.7997.jar from http://sourceforge.net/projects/plantuml/files/plantuml.7997.jar/download
 cp ~/Downloads/plantuml.7997.jar ~/tfs-ctrl/hackfest/yang/plantuml.jar
 
-sudo apt-get install -y wireshark
+# (done) Install WireShark
 #   When asked "allow non-root users to capture?" answer "yes"
+sudo apt-get install -y wireshark
+# Add current user to wireshark group to allow capturing as non-root (requires log-out & log-in, or reboot)
 sudo usermod -a -G wireshark $USER
 
 
@@ -24,34 +34,48 @@ sudo usermod -a -G wireshark $USER
 # YANG
 ################################################################################
 
-$ cd ~/tfs-ctrl/hackfest/yang
-$ cat topology.yang
-$ pyang -f tree topology.yang
-$ pyang -f tree topology.yang -o topology.tree
-$ pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang
-$ pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang -o topology-sample.xml
-$ pyang -f uml topology.yang -o topology.uml
-$ java -jar plantuml.jar topology.uml
+## GUIDED
+
+# Convert Topology YANG to Text-based tree
+pyang -f tree topology.yang
+pyang -f tree topology.yang -o topology.tree
 
+# Report a sample message following Topology YANG data model
+pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang
+pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang -o topology-sample.xml
 
+# Convert Topology YANG to UML
+pyang -f uml topology.yang -o topology.uml
+java -jar plantuml.jar topology.uml
 
-PYANGBIND
----------
-$ export PYBINDPLUGIN=`/usr/bin/env python3 -c \
+# Convert Topology YANG to Python bindings
+export PYBINDPLUGIN=`/usr/bin/env python -c \
 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
-$ echo $PYBINDPLUGIN
-$ pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py
-$ python3 topology.py
+echo $PYBINDPLUGIN
+pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py
 
+# Test creation of JSON-/XML-encoded Topology messages
+python topology.py
 
+## EXERCISE
 
-EXERCISE: CONNECTION
---------------------
-$ cd ~/tfs-ctrl/hackfest/yang/connection
-$ export PYBINDPLUGIN=`/usr/bin/env python3 -c \
-'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
-$ pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py
-$ python3 connection.py
+# Convert Connection YANG to Text-based tree
+pyang -f tree connection.yang
+
+# Report a sample message following Connection YANG data model
+pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations connection.yang
+
+# Convert Connection YANG to UML
+pyang -f uml connection.yang -o connection.uml
+java -jar plantuml.jar connection.uml
+
+# Convert Connection YANG to Python bindings
+export PYBINDPLUGIN=`/usr/bin/env python -c \
+    'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
+pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py
+
+# Test creation of JSON-/XML-encoded Connection messages
+python connection.py
 
 
 
@@ -59,25 +83,25 @@ $ python3 connection.py
 # NETCONF
 ################################################################################
 
+## GUIDED
+
 Run server:
-$ cd ~/tfs-ctrl/hackfest/netconf
-$ python3 server_topology.py
+cd ~/tfs-ctrl/hackfest/netconf
+python3 server_topology.py
 
 In another window, run client:
-$ cd ~/tfs-ctrl/hackfest/netconf
-$ python3 client_topology.py
-
+cd ~/tfs-ctrl/hackfest/netconf
+python3 client_topology.py
 
+## EXERCISE
 
-EXERCISE: NETCONF EDIT-CONFIG
------------------------------
 Run server:
-$ cd ~/tfs-ctrl/hackfest/netconf/connection
-$ python3 server_topology_connection.py
+cd ~/tfs-ctrl/hackfest/netconf/connection
+python3 server_topology_connection.py
 
 In another window, run client:
-$ cd ~/tfs-ctrl/hackfest/netconf/connection
-$ python3 client_connection.py
+cd ~/tfs-ctrl/hackfest/netconf/connection
+python3 client_connection.py
 
 
 
@@ -85,213 +109,158 @@ $ python3 client_connection.py
 # TAPI
 ################################################################################
 
-RUN TAPI SERVER:
-(if needed)
-$ pip install -r ~/tfs-ctrl/hackfest/tapi/server/requirements.txt
-$ cd ~/tfs-ctrl/hackfest/tapi/server
-$ python3 tapi_server.py
-
-RUN TAPI CLIENT (In a new window):
+## GUIDED
+
+# (done) Install dependencies
+cd ~/tfs-ctrl/hackfest/tapi/server
+pip install -r requirements.txt
+
+# (done) Build & Implement methods for the TAPI v2.1.3 server:
+cd ~/tfs-ctrl/hackfest/tapi
+wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar
+wget -O tapi-connectivity.yaml https://github.com/OpenNetworkingFoundation/TAPI/raw/v2.1.3/OAS/tapi-connectivity%402020-06-16.yaml
+java -jar swagger-codegen-cli-3.0.35.jar generate --input-spec tapi-connectivity.yaml \
+    --lang python-flask --output server --disable-examples --config codegen-config.json
+pip install connexion==2.14.1
+cd ~/tfs-ctrl/hackfest/tapi/server
+# Rename methods in "tapi_server/controllers/tapi_path_computation_controller.py" as follows:
+#   operations_tapi_path_computationcompute_p2_p_path_post => operations_tapi_path_computationcompute_p_2_p_path_post
+#   operations_tapi_path_computationdelete_p2_p_path_post => operations_tapi_path_computationdelete_p_2_p_path_post
+#   operations_tapi_path_computationoptimize_p2_ppath_post => operations_tapi_path_computationoptimize_p_2_ppath_post
+# Implement database based on Reference Implementation [Ref-3] in tapi/server/Acknowledgements.txt
+
+# Run the TAPI server:
+cd ~/tfs-ctrl/hackfest/tapi/server
+python3 -m tapi_server 8080 database/mini-ols-context.json
+
+# Run TAPI client using cURL (In a new window):
 $ cd ~/tfs-ctrl/hackfest/tapi/client
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/service-interface-point/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/service-interface-point/sip-pe1-uni1/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/owned-node-edge-point/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/owned-node-edge-point/NEP_PE_01_UNI1/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/link/PE1_NNI3_PI3_NNI1/
-
-CONNECTIONS:
-
-$ curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/ -d @cs1.json
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/
-$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connection/cs1/
-$ curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/
-
-
-EXERCISE: TAPI_APP
-$ cd ~/tfs-ctrl/hackfest/tapi/tapi_app
-$ python3 tapi_app.py
-
-
-== GRPC
-$ cd ~/tfs-ctrl/hackfest/grpc
-
-COMPILE connection.proto:
-$ python -m grpc_tools.protoc -I=. --python_out=connection/ connection.proto
-
-RUN CREATE AND LIST CONNECTION
-$ cd ~/tfs-ctrl/hackfest/grpc/connection
-$ python3 create.py connection.txt 
-$ python3 list.py connection.txt
-
-COMPILE connectionService.proto
-$ python -m grpc_tools.protoc -I=. --python_out=connectionService/ --grpc_python_out=connectionService/ connectionService.proto
-
-RUN SERVER
-$ cd ~/tfs-ctrl/hackfest/grpc/connectionService
-$ python3 connectionService_server.py
-
-RUN CLIENT (in another window)
-$ cd ~/tfs-ctrl/hackfest/grpc/connectionService
-$ python3 connectionService_client.py
-
-### EXERCISE
-COMPILE connectionServiceWithNotif.proto
-$ cd ~/tfs-ctrl/hackfest/grpc/
-$ python -m grpc_tools.protoc -I=. --python_out=connectionServiceWithNotif/ --grpc_python_out=connectionServiceWithNotif/ connectionServiceWithNotif.proto
-
-RUN SERVER
-$ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif
-$ python3 connectionServiceWithNotif_server.py
-
-RUN CLIENT (in another window)
-$ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif
-$ python3 connectionServiceWithNotif_client.py
-
-
-== GNMI
-$ cd /usr/share/gocode/src/ 
-$ export GOPATH=/usr/share/gocode/
-$ go run github.com/openconfig/ygot/generator/generator.go -generate_fakeroot -output_file github.com/google/gnxi/gnmi/modeldata/gostruct/generated.go -package_name gostruct github.com/rvilalta/OFC_SC472/yang/topology.yang 
-$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_target
-$ go run gnmi_target.go -bind_address :10161 -config ~/tfs-ctrl/hackfest/gnmi/topology.json --notls -alsologtostderr
-
-RUN CLIENT (in another window)
-$ export GOPATH=/usr/share/gocode/
-$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_get
-$ go run gnmi_get.go -notls -xpath "/topology/" -target_addr localhost:10161 -alsologtostderr 
-$ go run gnmi_get.go -notls -xpath "/topology/node[node-id=A]" -target_addr localhost:10161 -alsologtostderr
-
-USE PYTHON CLIENT
-$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_cli_py
-$ python py_gnmicli.py -n -m get -t localhost -p 10161 -x /topology -u foo -pass bar
-
-== KAFKA
-$ cd ~/tfs-ctrl/hackfest/kafka
-
-(INSTALL)
-$ pip3 install kafka-python
-$ wget https://ftp.cixug.es/apache/kafka/2.8.0/kafka_2.13-2.8.0.tgz
-$ tar -xzf kafka_2.13-2.8.0.tgz
-(RUN)
-$ cd kafka_2.13-2.8.0
-$ bin/zookeeper-server-start.sh config/zookeeper.properties
-(In new window)
-$ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0
-$ bin/kafka-server-start.sh config/server.properties
-
-CREATE TOPIC
-(In new window)
-$ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0
-$ bin/kafka-topics.sh --create --topic my-topic --bootstrap-server localhost:9092
-
-(In new window)
-$ cd ~/tfs-ctrl/hackfest/kafka
-$ python3 sub.py
- 
-(In new window)
-$ cd ~/tfs-ctrl/hackfest/kafka
-$ python3 pub.py
-
-== APPENDIX: CONFD
-$ cd ~/tfs-ctrl/hackfest/netconf
-$ unzip confd-basic-6.4.linux.x86_64.zip  
-$ cd confd-basic-6.4.linux.x86_64/
-$ ./confd-basic-6.4.linux.x86_64.installer.bin /root/confd/
-
-Data model compilation
-$ cd /root/confd/bin/
-$ ./confdc -c ~/tfs-ctrl/hackfest/yang/topology.yang
-
-Start ConfD
-$ ./confd --foreground -v --addloadpath .
-
-In another terminal, use ConfD-client to populate model
-$ cd /root/confd/bin/
-$ ./confd_cli
-> conf
-> topology node node1
-> exit
-> commit
-> exit
-> exit
-
-Use ConfD-client to show db
-$ ./confd_cli
-> conf
-> show full-configuration
-> exit
-> exit
-
-== RUN ONOS
-$ cd /root/onos-2.1.0/apache-karaf-4.2.3/bin/
-$ ./karaf clean
-> app activate org.onosproject.openflow
-> app activate org.onosproject.gui
-
-In another terminal, run mininet:
-$ mn --topo linear,3 --mac --controller=remote,ip=127.0.0.1,port=6653 --switch ovs,protocols=OpenFlow13
-
-In another terminal, we use ONOS REST API:
-$ curl -X GET -u onos:rocks --header 'Accept: application/json' http://localhost:8181/onos/v1/links | python -m json.tool
-$ cd ~/tfs-ctrl/hackfest/onos_api/
-$ python3 onos_topology.py 
+
+# Interrogate Context and SIPs:
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/service-interface-point=node-4-port-16-output/
+
+# Interrogate Topology, Nodes and Links:
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/link=link-4:2-2:4/
+
+# Create ConnectivityServices and Connections:
+curl -X POST -H "Content-Type: application/json" \
+    http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service/ \
+    -d @/home/tfs/tfs-ctrl/hackfest/tapi/client/cs1.json
+
+# Interrogate ConnectivityServices and Connections:
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/
+curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connection=cs1/
+
+# Delete ConnectivityServices and Connections:
+curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/
+
+
+## EXERCISE
+# Exercise: retrieve and draw the topology
+# solution in folder tapi_app
+
+cd ~/tfs-ctrl/hackfest/tapi/tapi_app
+python3 tapi_app.py
+
+
+
+################################################################################
+# Deploy TeraFlowSDN
+################################################################################
+
+# Check status of Kubernetes
+microk8s.status --wait-ready
+
+# Check all resources in Kubernetes
+microk8s.kubectl get all --all-namespaces
+
+# Deploy TeraFlowSDN
+cd ~/tfs-ctrl
+source my_deploy.sh 
+./deploy.sh 
+
+# Show status of your deployment
+(if new terminal) cd ~/tfs-ctrl && source my_deploy.sh
+./show_deploy.sh 
+
+# Show logs of a specific component
+(if new terminal) cd ~/tfs-ctrl && source my_deploy.sh
+scripts/show_logs_device.sh
+
 
 
 ################################################################################
-# OTHER MATERIAL
+# Programmable L3 routers
 ################################################################################
 
-== RESTCONF
+# (done) Build a Netconf server supporting basic OpenConfig data model
+
+# Start the Netconf/OpenConfig server
+cd ~/tfs-ctrl/hackfest/netconf-oc
+python3 server_openconfig.py 8300
+
+
+
+################################################################################
+# Service requests
+################################################################################
+
+## L3VPN service from JSON descriptors
+
+# (in a new terminal) Start OLS TAPI server:
+cd ~/tfs-ctrl/hackfest/tapi/server
+python3 -m tapi_server 8080 database/mini-ols-context.json
+
+# (in a new terminal) Start the Netconf/OpenConfig server for R1
+cd ~/tfs-ctrl/hackfest/netconf-oc
+python3 server_openconfig.py 8301
+
+# (in a new terminal) Start the Netconf/OpenConfig server for R2
+cd ~/tfs-ctrl/hackfest/netconf-oc
+python3 server_openconfig.py 8302
 
-=== YANG2SWAGGER
+# (in a new terminal) Start the Netconf/OpenConfig server for R3
+cd ~/tfs-ctrl/hackfest/netconf-oc
+python3 server_openconfig.py 8303
 
-$ cd ~/tfs-ctrl/hackfest/restconf
-(if needed)
-$ wget https://github.com/bartoszm/yang2swagger/releases/download/1.1.11/swagger-generator-cli-1.1.11-executable.jar
+# (in a new terminal) Start the Netconf/OpenConfig server for R4
+cd ~/tfs-ctrl/hackfest/netconf-oc
+python3 server_openconfig.py 8304
 
-Generate swagger files:
-$ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output topology.yaml topology
-$ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output connection.yaml connection
 
 
+############
+# Mock OSM
+############
 
-=== SERVER
-$ cd ~/tfs-ctrl/hackfest/restconf
-(if needed)
-$ wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.11/swagger-codegen-cli-3.0.11.jar -O swagger-codegen-cli.jar
+$ cd ~/tfs-ctrl/hackfest/
+$ python -m mock_osm
+Welcome to the MockOSM shell.
+Type help or ? to list commands.
 
-Create the server:
-$ mkdir ~/tfs-ctrl/hackfest/restconf/server
-$ java -jar swagger-codegen-cli.jar generate -i connection.yaml -l python-flask -o server
+(mock-osm) create
+Service b8c99e2c-39d8-424d-9833-554634269555 created
+# Service should be created in TFS. Check "Slice" and "Service" pages on WebUI.
+# Check configuration rules in "Devices"
 
-Run the server:
-$ cd ~/tfs-ctrl/hackfest/restconf/server
-$ pip3 install -r requirements.txt
-(Open ~/tfs-ctrl/hackfest/restconf/server/swagger_server/swagger/swagger.yaml and modify all: "name: connection_id" for "name: connection-id")
-RUN AUTOGENERATED SERVER
-$ python3 -m swagger_server
+(mock-osm) status
+response.status_code=200
+Status of Service b8c99e2c-39d8-424d-9833-554634269555 is {'sdn_status': 'ACTIVE'}
 
-(you have the solution in ~/tfs-ctrl/hackfest/restconf/connectionserver )
+(mock-osm) delete
+Service b8c99e2c-39d8-424d-9833-554634269555 deleted
+# Service should be removed from TFS. Check "Slice" and "Service" pages on WebUI.
+# Check configuration rules in "Devices"
 
-RUN CURL AS CLIENT (In another window)
-$ cd ~/tfs-ctrl/hackfest/restconf/
-$ curl -X POST -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection/ -d@conn1.json
-$ curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/
-$ curl -X DELETE -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/
+(mock-osm) exit
+Bye!
 
 
-=== Exercise: RESTCONF TOPOLOGY ===
-$ mkdir ~/tfs-ctrl/hackfest/restconf/topologyserver
-$ java -jar swagger-codegen-cli.jar generate -i topology.yaml -l python-flask -o topologyserver
-$ cd ~/tfs-ctrl/hackfest/restconf/topologyserver
-(Open ~/tfs-ctrl/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml and modify all: "name: link_id" for "name: link-id", same for node and port)
-$ python3 -m swagger_server
 
-RUN CURL AS CLIENT (In another window)
-$curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/topology/
diff --git a/hackfest/gnmi/commands.txt b/hackfest/gnmi/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6fae7f9a8fc8b9b69d364b1d279aca80759c90ef
--- /dev/null
+++ b/hackfest/gnmi/commands.txt
@@ -0,0 +1,17 @@
+== GNMI
+$ cd /usr/share/gocode/src/ 
+$ export GOPATH=/usr/share/gocode/
+$ go run github.com/openconfig/ygot/generator/generator.go -generate_fakeroot -output_file github.com/google/gnxi/gnmi/modeldata/gostruct/generated.go -package_name gostruct github.com/rvilalta/OFC_SC472/yang/topology.yang 
+$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_target
+$ go run gnmi_target.go -bind_address :10161 -config ~/tfs-ctrl/hackfest/gnmi/topology.json --notls -alsologtostderr
+
+RUN CLIENT (in another window)
+$ export GOPATH=/usr/share/gocode/
+$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_get
+$ go run gnmi_get.go -notls -xpath "/topology/" -target_addr localhost:10161 -alsologtostderr 
+$ go run gnmi_get.go -notls -xpath "/topology/node[node-id=A]" -target_addr localhost:10161 -alsologtostderr
+
+USE PYTHON CLIENT
+$ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_cli_py
+$ python py_gnmicli.py -n -m get -t localhost -p 10161 -x /topology -u foo -pass bar
+
diff --git a/hackfest/grpc/commands.txt b/hackfest/grpc/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e0148b180c03841098781563976467d980abc464
--- /dev/null
+++ b/hackfest/grpc/commands.txt
@@ -0,0 +1,36 @@
+== GRPC
+$ cd ~/tfs-ctrl/hackfest/grpc
+
+COMPILE connection.proto:
+$ python -m grpc_tools.protoc -I=. --python_out=connection/ connection.proto
+
+RUN CREATE AND LIST CONNECTION
+$ cd ~/tfs-ctrl/hackfest/grpc/connection
+$ python3 create.py connection.txt 
+$ python3 list.py connection.txt
+
+COMPILE connectionService.proto
+$ python -m grpc_tools.protoc -I=. --python_out=connectionService/ --grpc_python_out=connectionService/ connectionService.proto
+
+RUN SERVER
+$ cd ~/tfs-ctrl/hackfest/grpc/connectionService
+$ python3 connectionService_server.py
+
+RUN CLIENT (in another window)
+$ cd ~/tfs-ctrl/hackfest/grpc/connectionService
+$ python3 connectionService_client.py
+
+### EXERCISE
+COMPILE connectionServiceWithNotif.proto
+$ cd ~/tfs-ctrl/hackfest/grpc/
+$ python -m grpc_tools.protoc -I=. --python_out=connectionServiceWithNotif/ --grpc_python_out=connectionServiceWithNotif/ connectionServiceWithNotif.proto
+
+RUN SERVER
+$ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif
+$ python3 connectionServiceWithNotif_server.py
+
+RUN CLIENT (in another window)
+$ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif
+$ python3 connectionServiceWithNotif_client.py
+
+
diff --git a/hackfest/kafka/commands.txt b/hackfest/kafka/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f29d6020b5fa044b1d60020b30075c763161f31f
--- /dev/null
+++ b/hackfest/kafka/commands.txt
@@ -0,0 +1,27 @@
+== KAFKA
+$ cd ~/tfs-ctrl/hackfest/kafka
+
+(INSTALL)
+$ pip3 install kafka-python
+$ wget https://ftp.cixug.es/apache/kafka/2.8.0/kafka_2.13-2.8.0.tgz
+$ tar -xzf kafka_2.13-2.8.0.tgz
+(RUN)
+$ cd kafka_2.13-2.8.0
+$ bin/zookeeper-server-start.sh config/zookeeper.properties
+(In new window)
+$ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0
+$ bin/kafka-server-start.sh config/server.properties
+
+CREATE TOPIC
+(In new window)
+$ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0
+$ bin/kafka-topics.sh --create --topic my-topic --bootstrap-server localhost:9092
+
+(In new window)
+$ cd ~/tfs-ctrl/hackfest/kafka
+$ python3 sub.py
+ 
+(In new window)
+$ cd ~/tfs-ctrl/hackfest/kafka
+$ python3 pub.py
+
diff --git a/hackfest/netconf-oc/_commands.md b/hackfest/netconf-oc/_commands.md
deleted file mode 100644
index c8f1cff029b2ad992471aa350fc48aafbe88f9d6..0000000000000000000000000000000000000000
--- a/hackfest/netconf-oc/_commands.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# NETCONF TFS exercise
-
-## 1. Interrogate Topology
-
-```bash
-# Configure basic NetConf/OpenConfig server
-
-mkdir -p ~/yang-netconf/netconf-tfs/{git_openconfig,openconfig}
-git clone https://github.com/openconfig/public.git ~/yang-netconf/netconf-tfs/git_openconfig
-
-cd ~/yang-netconf/netconf-tfs
-
-export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
-pyang --plugindir $PYBINDPLUGIN -p git_openconfig/release/models/ -f pybind --split-class-dir openconfig \
-    git_openconfig/release/models/interfaces/openconfig-interfaces.yang \
-    git_openconfig/release/models/interfaces/openconfig-if-ethernet.yang \
-    git_openconfig/release/models/platform/openconfig-platform.yang \
-    git_openconfig/release/models/platform/openconfig-platform-port.yang
-
-python3 serverOpenConfig.py
-
-# Terminal 2 (client)
-cd ~/yang-netconf/netconf
-python3 clientTopology.py
-```
-
-### 2.2. Report a sample message following Topology YANG data model
-```bash
-mkdir -p sample-xml-skeleton
-pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang -o sample-xml-skeleton/topology.xml
-```
-
-### 2.3. Convert Topology YANG to UML
-```bash
-mkdir -p uml
-pyang -f uml topology.yang -o uml/topology.uml
-java -jar plantuml.jar uml/topology.uml
-```
-
-### 2.4. Convert Topology YANG to Python bindings
-```bash
-export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
-pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py
-```
-
-### 2.5. Test creation of JSON-/XML-encoded Topology messages
-```bash
-python topology.py
-```
-
-
-## 3. Connection YANG data model (exercise solution)
-
-### 3.1. Convert Connection YANG to Text-based tree
-```bash
-mkdir -p tree
-pyang -f tree connection.yang -o tree/connection.txt
-```
-
-### 3.2. Report a sample message following Connection YANG data model
-```bash
-mkdir -p sample-xml-skeleton
-pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations connection.yang -o sample-xml-skeleton/connection.xml
-```
-
-### 3.3. Convert Connection YANG to UML
-```bash
-mkdir -p uml
-pyang -f uml connection.yang -o uml/connection.uml
-java -jar plantuml.jar uml/connection.uml
-```
-
-### 3.4. Convert Connection YANG to Python bindings
-```bash
-export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
-pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py
-```
-
-### 3.5. Test creation of JSON-/XML-encoded Connection messages
-```bash
-python topology.py
-```
diff --git a/hackfest/netconf-oc/build-instructions.txt b/hackfest/netconf-oc/build-instructions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c485bc006d25244d170f6c515ea985d7cec6d75b
--- /dev/null
+++ b/hackfest/netconf-oc/build-instructions.txt
@@ -0,0 +1,14 @@
+# Build a Netconf server supporting basic OpenConfig data model
+
+mkdir -p ~/tfs-ctrl/netconf-oc/{git_openconfig,openconfig}
+
+git clone https://github.com/openconfig/public.git ~/tfs-ctrl/netconf-oc/git_openconfig
+
+cd ~/tfs-ctrl/netconf-oc
+
+export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'`
+pyang --plugindir $PYBINDPLUGIN -p git_openconfig/release/models/ -f pybind --split-class-dir openconfig \
+    git_openconfig/release/models/interfaces/openconfig-interfaces.yang \
+    git_openconfig/release/models/interfaces/openconfig-if-ethernet.yang \
+    git_openconfig/release/models/platform/openconfig-platform.yang \
+    git_openconfig/release/models/platform/openconfig-platform-port.yang
diff --git a/hackfest/netconf/connection/topology.xml b/hackfest/netconf/connection/topology.xml
index 64f95dd7b1b8531937468f3500bde0b63e3b606a..93af480850b540669f133a76b12519f5554b8850 100644
--- a/hackfest/netconf/connection/topology.xml
+++ b/hackfest/netconf/connection/topology.xml
@@ -21,5 +21,3 @@
     </link>
   </topology>
 </topology>
-
-
diff --git a/hackfest/netconf/topology.xml b/hackfest/netconf/topology.xml
index 64f95dd7b1b8531937468f3500bde0b63e3b606a..93af480850b540669f133a76b12519f5554b8850 100644
--- a/hackfest/netconf/topology.xml
+++ b/hackfest/netconf/topology.xml
@@ -21,5 +21,3 @@
     </link>
   </topology>
 </topology>
-
-
diff --git a/hackfest/onos_api/commands.txt b/hackfest/onos_api/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cac0169e63fac4b16bee718ab0720e2589ffb103
--- /dev/null
+++ b/hackfest/onos_api/commands.txt
@@ -0,0 +1,45 @@
+== APPENDIX: CONFD
+$ cd ~/tfs-ctrl/hackfest/netconf
+$ unzip confd-basic-6.4.linux.x86_64.zip  
+$ cd confd-basic-6.4.linux.x86_64/
+$ ./confd-basic-6.4.linux.x86_64.installer.bin /root/confd/
+
+Data model compilation
+$ cd /root/confd/bin/
+$ ./confdc -c ~/tfs-ctrl/hackfest/yang/topology.yang
+
+Start ConfD
+$ ./confd --foreground -v --addloadpath .
+
+In another terminal, use ConfD-client to populate model
+$ cd /root/confd/bin/
+$ ./confd_cli
+> conf
+> topology node node1
+> exit
+> commit
+> exit
+> exit
+
+Use ConfD-client to show db
+$ ./confd_cli
+> conf
+> show full-configuration
+> exit
+> exit
+
+== RUN ONOS
+$ cd /root/onos-2.1.0/apache-karaf-4.2.3/bin/
+$ ./karaf clean
+> app activate org.onosproject.openflow
+> app activate org.onosproject.gui
+
+In another terminal, run mininet:
+$ mn --topo linear,3 --mac --controller=remote,ip=127.0.0.1,port=6653 --switch ovs,protocols=OpenFlow13
+
+In another terminal, we use ONOS REST API:
+$ curl -X GET -u onos:rocks --header 'Accept: application/json' http://localhost:8181/onos/v1/links | python -m json.tool
+$ cd ~/tfs-ctrl/hackfest/onos_api/
+$ python3 onos_topology.py 
+
+
diff --git a/hackfest/restconf/commands.txt b/hackfest/restconf/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2eac80cf60d58675981983c722bb7d2fdcbd84bf
--- /dev/null
+++ b/hackfest/restconf/commands.txt
@@ -0,0 +1,48 @@
+== RESTCONF
+
+=== YANG2SWAGGER
+
+$ cd ~/tfs-ctrl/hackfest/restconf
+(if needed)
+$ wget https://github.com/bartoszm/yang2swagger/releases/download/1.1.11/swagger-generator-cli-1.1.11-executable.jar
+
+Generate swagger files:
+$ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output topology.yaml topology
+$ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output connection.yaml connection
+
+
+
+=== SERVER
+$ cd ~/tfs-ctrl/hackfest/restconf
+(if needed)
+$ wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.11/swagger-codegen-cli-3.0.11.jar -O swagger-codegen-cli.jar
+
+Create the server:
+$ mkdir ~/tfs-ctrl/hackfest/restconf/server
+$ java -jar swagger-codegen-cli.jar generate -i connection.yaml -l python-flask -o server
+
+Run the server:
+$ cd ~/tfs-ctrl/hackfest/restconf/server
+$ pip3 install -r requirements.txt
+(Open ~/tfs-ctrl/hackfest/restconf/server/swagger_server/swagger/swagger.yaml and modify all: "name: connection_id" for "name: connection-id")
+RUN AUTOGENERATED SERVER
+$ python3 -m swagger_server
+
+(you have the solution in ~/tfs-ctrl/hackfest/restconf/connectionserver )
+
+RUN CURL AS CLIENT (In another window)
+$ cd ~/tfs-ctrl/hackfest/restconf/
+$ curl -X POST -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection/ -d@conn1.json
+$ curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/
+$ curl -X DELETE -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/
+
+
+=== Exercise: RESTCONF TOPOLOGY ===
+$ mkdir ~/tfs-ctrl/hackfest/restconf/topologyserver
+$ java -jar swagger-codegen-cli.jar generate -i topology.yaml -l python-flask -o topologyserver
+$ cd ~/tfs-ctrl/hackfest/restconf/topologyserver
+(Open ~/tfs-ctrl/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml and modify all: "name: link_id" for "name: link-id", same for node and port)
+$ python3 -m swagger_server
+
+RUN CURL AS CLIENT (In another window)
+$curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/topology/
diff --git a/hackfest/tapi/commands.txt b/hackfest/tapi/commands.txt
deleted file mode 100644
index 4861aeecd372837510c359cf2563cdc20e3c01f5..0000000000000000000000000000000000000000
--- a/hackfest/tapi/commands.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-# Commands to build TAPI v2.1.3 Server:
-
-# Acknowledgements and References:
-# [Ref-1]: https://github.com/OpenNetworkingFoundation/TAPI
-# [Ref-2]: https://github.com/OpenNetworkingFoundation/TAPI/tree/v2.1.3/YANG
-# [Ref-3]: https://github.com/OpenNetworkingFoundation/TAPI/tree/develop/RI
-
-cd ~/tfs-ctrl/hackfest/tapi
-wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar
-wget -O tapi-connectivity.yaml https://github.com/OpenNetworkingFoundation/TAPI/raw/v2.1.3/OAS/tapi-connectivity%402020-06-16.yaml
-java -jar swagger-codegen-cli-3.0.35.jar generate --input-spec tapi-connectivity.yaml \
-    --lang python-flask --output server --disable-examples --config codegen-config.json
-pip install connexion==2.14.1
-cd ~/tfs-ctrl/hackfest/tapi/server
-# Rename methods in "tapi_server/controllers/tapi_path_computation_controller.py" as follows:
-#   operations_tapi_path_computationcompute_p2_p_path_post => operations_tapi_path_computationcompute_p_2_p_path_post
-#   operations_tapi_path_computationdelete_p2_p_path_post => operations_tapi_path_computationdelete_p_2_p_path_post
-#   operations_tapi_path_computationoptimize_p2_ppath_post => operations_tapi_path_computationoptimize_p_2_ppath_post
-# Implement database based on Reference Implementation [Ref-3]
-python3 -m tapi_server
-
-RUN TAPI CLIENT (In a new window):
-# Context:
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/service-interface-point=node-4-port-16-output/
-
-# Topology:
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/link=link-4:2-2:4/
-
-# Connection:
-curl -X POST -H "Content-Type: application/json" \
-    http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service/ \
-    -d @/home/tfs/tfs-ctrl/hackfest/tapi/client/cs1.json
-
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connection=cs1/
-
-curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/
-
-
-# Exercise: retrieve and draw the topology
-solution in folder tapi_app
-
-
-Not testable since there is no path computation 
-curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-odu-pi-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/connection-end-point={cep-uuid}/
diff --git a/hackfest/tapi/server/Acknowledgements.txt b/hackfest/tapi/server/Acknowledgements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..288a31e12df8aef0f2c8098c64a2f48b9fc11faf
--- /dev/null
+++ b/hackfest/tapi/server/Acknowledgements.txt
@@ -0,0 +1,3 @@
+# [Ref-1]: https://github.com/OpenNetworkingFoundation/TAPI
+# [Ref-2]: https://github.com/OpenNetworkingFoundation/TAPI/tree/v2.1.3/YANG
+# [Ref-3]: https://github.com/OpenNetworkingFoundation/TAPI/tree/develop/RI
diff --git a/hackfest/tapi/server/tapi_server/database/mini-ols-context.json b/hackfest/tapi/server/tapi_server/database/mini-ols-context.json
index 6bfe9e402eb688874aae14caaf2bd1f256469657..59a4fb7cfb54df9a101ac5eda848f36553791704 100644
--- a/hackfest/tapi/server/tapi_server/database/mini-ols-context.json
+++ b/hackfest/tapi/server/tapi_server/database/mini-ols-context.json
@@ -308,7 +308,7 @@
     ],
     "topology-context": {
         "nw-topology-service": {
-            "uuid": "ols-topo",
+            "uuid": "ols-ctx",
             "topology": [{"topology-uuid": "ols-topo"}]
         },
         "topology": [
diff --git a/hackfest/tapi/tapi_app/tapi_app.py b/hackfest/tapi/tapi_app/tapi_app.py
index 08d6facf4ab55be932e78003fdafe8336ced3bcf..195306c7b1e0f586f03b1c625846550a2cc06c57 100644
--- a/hackfest/tapi/tapi_app/tapi_app.py
+++ b/hackfest/tapi/tapi_app/tapi_app.py
@@ -1,55 +1,51 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
-import requests
+import json, requests, networkx as nx
 from requests.auth import HTTPBasicAuth
-import json
-import networkx as nx
 
 IP = '127.0.0.1'
 PORT = 8080
-USER = ''
-PASS = ''
 TOPO_UUID = 'ols-topo'
+TOPO_URL = 'http://{:s}:{:d}/restconf/data/tapi-common:context/'\
+    'tapi-topology:topology-context/topology={:s}/'
 
-TOPO_LIST_URL = 'http://{:s}:{:d}/restconf/data/tapi-common:context/tapi-topology:topology-context/topology={:s}/'
-
-def retrieveTopology(ip, port, user, password, topo_uuid):
+def retrieve_topology(ip, port, topo_uuid, user='', passwd=''):
     print ("Reading network-topology")
-    topologies = []
-    topo_list_url = TOPO_LIST_URL.format(ip, port, topo_uuid)
-    response = requests.get(topo_list_url, auth=HTTPBasicAuth(user, password))
-    topologies.append(response.json())
-    print ("Retrieved Topology: " + json.dumps(response.json(), indent=4))
-    return topologies
-
-def draw_topologies (topologies):
+    topo_url = TOPO_URL.format(ip, port, topo_uuid)
+    response = requests.get(topo_url, auth=HTTPBasicAuth(user, passwd))
+    topology = response.json()
+    print ("Retrieved Topology: " + json.dumps(topology, indent=4))
+    return topology
+
+def to_png_matplotlib(nwk_graph, topo_uuid):
+    import matplotlib.pyplot as plt
+    nx.draw(nwk_graph, pos=nx.spring_layout(nwk_graph, scale=500))
+    plt.show(block=False)
+    plt.savefig('{:s}.png'.format(topo_uuid), format='PNG')
+    plt.close()
+
+def to_png_pydot(nwk_graph, topo_uuid):
+    from networkx.drawing.nx_pydot import write_dot, to_pydot
+    write_dot(nwk_graph, '{:s}.dot'.format(topo_uuid))
+    dot_graph = to_pydot(nwk_graph)
+    with open('{:s}.png'.format(topo_uuid), 'wb') as f:
+        f.write(dot_graph.create(format='png'))
+
+def draw_topology(topology):
     nwk_graph = nx.DiGraph()
 
-    for topo in topologies:
-        topo_uuid = topo['uuid']
-        for node in topo['node']:
-            if node['owned-node-edge-point']:
-                nwk_graph.add_node(node['uuid'])
-
-        for link in topo['link']:
-            node1 = link['node-edge-point'][0]['node-uuid']
-            node2 = link['node-edge-point'][1]['node-uuid']
-            nwk_graph.add_edge(node1, node2)
-
-        # Using Matplotlib
-        #import matplotlib.pyplot as plt
-        #nx.draw(nwk_graph, pos=nx.spring_layout(nwk_graph, scale=500))
-        #plt.show(block=False)
-        #plt.savefig('{:s}.png'.format(TOPO_UUID), format='PNG')
-
-        # Using Pydot and Graphviz
-        from networkx.drawing.nx_pydot import write_dot, to_pydot
-        write_dot(nwk_graph, '{:s}.dot'.format(topo_uuid))
-        dot_graph = to_pydot(nwk_graph)
-        with open('{:s}.png'.format(topo_uuid), 'wb') as f:
-            f.write(dot_graph.create(format='png'))
+    for node in topology['node']:
+        if node['owned-node-edge-point']:
+            nwk_graph.add_node(node['uuid'])
+
+    for link in topology['link']:
+        node1 = link['node-edge-point'][0]['node-uuid']
+        node2 = link['node-edge-point'][1]['node-uuid']
+        nwk_graph.add_edge(node1, node2)
+
+    #to_png_matplotlib(nwk_graph, topology['uuid'])
+    to_png_pydot(nwk_graph, topology['uuid'])
 
 if __name__ == "__main__":
-    topologies = retrieveTopology(IP, PORT, USER, PASS, TOPO_UUID)
-    draw_topologies(topologies)
+    draw_topology(retrieve_topology(IP, PORT, TOPO_UUID))
diff --git a/hackfest/tfs-descriptors/context-topology.json b/hackfest/tfs-descriptors/context-topology.json
new file mode 100644
index 0000000000000000000000000000000000000000..36b3c44fd61fdec9d208a82a11d5a16c3671d004
--- /dev/null
+++ b/hackfest/tfs-descriptors/context-topology.json
@@ -0,0 +1,19 @@
+{
+    "contexts": [
+        {
+            "context_id": {"context_uuid": {"uuid": "admin"}},
+            "topology_ids": [],
+            "service_ids": []
+        }
+    ],
+    "topologies": [
+        {
+            "topology_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}},
+                "topology_uuid": {"uuid": "admin"}
+            },
+            "device_ids": [],
+            "link_ids": []
+        }
+    ]
+}
diff --git a/hackfest/tfs-descriptors/device-all.json b/hackfest/tfs-descriptors/device-all.json
new file mode 100644
index 0000000000000000000000000000000000000000..ff9e529348a26409549eeffc2ec976443c5e273b
--- /dev/null
+++ b/hackfest/tfs-descriptors/device-all.json
@@ -0,0 +1,84 @@
+{
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "R1"}},
+            "device_type": "packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8301"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin",
+                    "force_running": false, "hostkey_verify": false, "look_for_keys": false,
+                    "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"},
+                    "manager_params": {"timeout" : 120}
+                }}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [1],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R2"}},
+            "device_type": "packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8302"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin",
+                    "force_running": false, "hostkey_verify": false, "look_for_keys": false,
+                    "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"},
+                    "manager_params": {"timeout" : 120}
+                }}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [1],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R3"}},
+            "device_type": "packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8303"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin",
+                    "force_running": false, "hostkey_verify": false, "look_for_keys": false,
+                    "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"},
+                    "manager_params": {"timeout" : 120}
+                }}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [1],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R4"}},
+            "device_type": "packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8304"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin",
+                    "force_running": false, "hostkey_verify": false, "look_for_keys": false,
+                    "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"},
+                    "manager_params": {"timeout" : 120}
+                }}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [1],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "OLS"}},
+            "device_type": "open-line-system",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [2],
+            "device_endpoints": []
+        }
+    ]
+}
diff --git a/hackfest/tfs-descriptors/device-netconf-openconfig.json b/hackfest/tfs-descriptors/device-netconf-openconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..7e01f037e744493a8cd1190b2510ed3d4d1c86aa
--- /dev/null
+++ b/hackfest/tfs-descriptors/device-netconf-openconfig.json
@@ -0,0 +1,21 @@
+{
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "R1"}},
+            "device_type": "packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8300"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin",
+                    "force_running": false, "hostkey_verify": false, "look_for_keys": false,
+                    "allow_agent": false, "delete_rule": true, "device_params": {"name": "default"},
+                    "manager_params": {"timeout" : 15}
+                }}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [1],
+            "device_endpoints": []
+        }
+    ]
+}
diff --git a/hackfest/tfs-descriptors/device-tapi-ols.json b/hackfest/tfs-descriptors/device-tapi-ols.json
new file mode 100644
index 0000000000000000000000000000000000000000..3dcdc562edb50e0b63e69f5745600110dd42151c
--- /dev/null
+++ b/hackfest/tfs-descriptors/device-tapi-ols.json
@@ -0,0 +1,16 @@
+{
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "OLS"}},
+            "device_type": "open-line-system",
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [2],
+            "device_endpoints": []
+        }
+    ]
+}
diff --git a/hackfest/tfs-descriptors/links.json b/hackfest/tfs-descriptors/links.json
new file mode 100644
index 0000000000000000000000000000000000000000..8a991fd622ac89bcb6fafed5abe61de0c6e17641
--- /dev/null
+++ b/hackfest/tfs-descriptors/links.json
@@ -0,0 +1,63 @@
+{
+    "links": [
+        {
+            "link_id": {"link_uuid": {"uuid": "R1/1/1==OLS/node-1-port-15-input"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}},
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-1-port-15-input"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "OLS/node-1-port-15-output==R1/1/1"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-1-port-15-output"}},
+                {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}}
+            ]
+        },
+
+        {
+            "link_id": {"link_uuid": {"uuid": "R2/1/1==OLS/node-2-port-15-input"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}},
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-2-port-15-input"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "OLS/node-2-port-15-output==R2/1/1"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-2-port-15-output"}},
+                {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}}
+            ]
+        },
+
+        {
+            "link_id": {"link_uuid": {"uuid": "R3/1/1==OLS/node-3-port-15-input"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}},
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-3-port-15-input"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "OLS/node-3-port-15-output==R3/1/1"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-3-port-15-output"}},
+                {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}}
+            ]
+        },
+
+        {
+            "link_id": {"link_uuid": {"uuid": "R4/1/1==OLS/node-4-port-15-input"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "1/1"}},
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-4-port-15-input"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "OLS/node-4-port-15-output==R4/1/1"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-4-port-15-output"}},
+                {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "1/1"}}
+            ]
+        }
+    ]
+}
diff --git a/hackfest/netconf-oc/tfs-device-descriptor.json b/hackfest/tfs-descriptors/old/device.json
similarity index 100%
rename from hackfest/netconf-oc/tfs-device-descriptor.json
rename to hackfest/tfs-descriptors/old/device.json
diff --git a/hackfest/netconf-oc/tfs-service-descriptor.json b/hackfest/tfs-descriptors/old/service.json
similarity index 100%
rename from hackfest/netconf-oc/tfs-service-descriptor.json
rename to hackfest/tfs-descriptors/old/service.json
diff --git a/hackfest/tfs-descriptors/service-l3vpn.json b/hackfest/tfs-descriptors/service-l3vpn.json
new file mode 100644
index 0000000000000000000000000000000000000000..457ba1a509aebc5eaea8caa37a09ac62ef286f32
--- /dev/null
+++ b/hackfest/tfs-descriptors/service-l3vpn.json
@@ -0,0 +1,44 @@
+{
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}},
+                "service_uuid": {"uuid": "netx-l3-svc"}
+            },
+            "service_type": 1,
+            "service_status": {"service_status": 1},
+            "service_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/2"}},
+                {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/2"}}
+            ],
+            "service_constraints": [
+                {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "10.0"}},
+                {"custom": {"constraint_type": "latency[ms]", "constraint_value": "15.2"}}
+            ],
+            "service_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "/settings", "resource_value": {
+                    "address_families": ["IPV4"],
+                    "bgp_as": 65000,
+                    "bgp_route_target": "65000:333",
+                    "mtu": 1512
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[1/2]/settings", "resource_value": {
+                    "address_ip": "3.3.2.1",
+                    "address_prefix": 24,
+                    "route_distinguisher": "65000:123",
+                    "router_id": "10.10.10.1",
+                    "sub_interface_index": 400,
+                    "vlan_id": 400
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R3]/endpoint[1/2]/settings", "resource_value": {
+                    "address_ip": "3.3.1.1",
+                    "address_prefix": 24,
+                    "route_distinguisher": "65000:321",
+                    "router_id": "20.20.20.1",
+                    "sub_interface_index": 400,
+                    "vlan_id": 500
+                }}}
+            ]}
+        }
+    ]
+}
diff --git a/hackfest/yang/connection/connection.py b/hackfest/yang/connection/connection.py
index a6f573a82799e5b7db7c5a8e87f9f933649bc069..c404d2f5c06508a5b23d733b618dc16dc0b20a9f 100644
--- a/hackfest/yang/connection/connection.py
+++ b/hackfest/yang/connection/connection.py
@@ -3,12 +3,13 @@ from pyangbind.lib.serialise import pybindIETFXMLEncoder
 import pyangbind.lib.pybindJSON as pybindJSON
 
 con = connection()
-con1=con.connection.add("con1")
+con1 = con.connection.add("con1")
 con1.source_node = "node1"
 con1.target_node = "node2"
 con1.source_port = "node1portA"
 con1.target_port = "node2portA"
 con1.bandwidth = 1000
 con1.layer_protocol_name = "OPTICAL"
+
 print(pybindIETFXMLEncoder.serialise(con))
 print(pybindJSON.dumps(con))
diff --git a/hackfest/yang/topology.py b/hackfest/yang/topology.py
index dc32ca4ec9d42f747145c7f90959266b27b12aa3..441300fb5ca91243e55bbd1995b6610109b52d7e 100644
--- a/hackfest/yang/topology.py
+++ b/hackfest/yang/topology.py
@@ -3,14 +3,18 @@ from pyangbind.lib.serialise import pybindIETFXMLEncoder
 import pyangbind.lib.pybindJSON as pybindJSON
 
 topo = topology()
-node1=topo.topology.node.add("node1")
+
+node1 = topo.topology.node.add("node1")
 node1.port.add("node1portA")
-node2=topo.topology.node.add("node2")
+
+node2 = topo.topology.node.add("node2")
 node2.port.add("node2portA")
-link=topo.topology.link.add("link1")
+
+link = topo.topology.link.add("link1")
 link.source_node = "node1"
 link.target_node = "node2"
 link.source_port = "node1portA"
 link.target_port = "node2portA"
+
 print(pybindIETFXMLEncoder.serialise(topo))
-print(pybindJSON.dumps(topo))
\ No newline at end of file
+print(pybindJSON.dumps(topo))