diff --git a/Makefile b/Makefile
index d1d601892858dc3c67f710ae3f9b7436c419af68..a273315fa0f26e32db65cfd44e3b7acdbee3a7e9 100644
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,7 @@ virt-manager-example-start: build containerize-plugin-registry
 virt-manager-example-stop:
 	./scripts/manage_virt_env.sh --mode stop --topology dev_env_data/clab/basic_two_aristas.yaml
 
-dev-env-start: containerize-gosdn containerize-plugin-registry
+dev-env-start: generate-gnmi-target-certs generate-gosdn-certs containerize-gosdn containerize-plugin-registry
 	./scripts/simple-dev-setup.sh --mode start --topology dev_env_data/clab/basic_two_gnmi_targets.yaml
 
 dev-env-stop:
diff --git a/dev_env_data/docker-compose/integration-test_docker-compose.yml b/dev_env_data/docker-compose/integration-test_docker-compose.yml
index 38e097c985336790a3b95521f186729cd471ad3a..ce513ece3079dd8e0dd595d3559122fb2c6ab5b6 100644
--- a/dev_env_data/docker-compose/integration-test_docker-compose.yml
+++ b/dev_env_data/docker-compose/integration-test_docker-compose.yml
@@ -9,6 +9,14 @@ services:
       MONGO_INITDB_ROOT_USERNAME: root
       MONGO_INITDB_ROOT_PASSWORD: example
 
+  mongo-express:
+    image: mongo-express:0.54.0
+    ports:
+        - 127.0.0.1:8083:8081
+    environment:
+      ME_CONFIG_MONGODB_ADMINUSERNAME: root
+      ME_CONFIG_MONGODB_ADMINPASSWORD: example
+
   rabbitmq:
     image: rabbitmq:3-management
     healthcheck:
diff --git a/integration-tests/topology_tests/topology_test.go b/integration-tests/topology_tests/topology_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5e6a44baffc7dcf14a55f9dc5dbef11bd8ac9a3d
--- /dev/null
+++ b/integration-tests/topology_tests/topology_test.go
@@ -0,0 +1,158 @@
+package integration_test_topology
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	topologyPb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology"
+	integration_test_utils "code.fbi.h-da.de/danet/gosdn/integration-tests/integrationTestUtils"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+)
+
+// The connection to the controller to use in each test.
+var conn *grpc.ClientConn
+
+// The context containing the credentials when authenticated.
+var ctx context.Context
+
+// A defaultSDN config with default/empty values.
+var defaultSDNConfig string
+
+func TestMain(m *testing.M) {
+	localConn, localCtx, err := integration_test_utils.CreateSecureConnection()
+	//localConn, localCtx, err := integration_test_utils.CreateConnection()
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	conn = localConn
+	ctx = localCtx
+
+	sndConfig, err := integration_test_utils.ExportCurrentSDNConfig(conn, ctx)
+	defaultSDNConfig = sndConfig
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	m.Run()
+}
+
+func TestCreateTopologyAndGetIt(t *testing.T) {
+	defer integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig)
+
+	addLinkRequest := topologyPb.AddLinkRequest{
+		Link: &topologyPb.Link{
+			Name:       "Link1",
+			SourceNode: &topologyPb.Node{Name: "Node1"},
+			TargetNode: &topologyPb.Node{Name: "Node2"},
+			SourcePort: &topologyPb.Port{Name: "Port1",
+				Configuration: &topologyPb.Configuration{
+					Ip:           "10.0.0.1",
+					PrefixLength: 24}},
+			TargetPort: &topologyPb.Port{Name: "Port2",
+				Configuration: &topologyPb.Configuration{
+					Ip:           "10.0.0.2",
+					PrefixLength: 24}}},
+	}
+
+	topologyService := topologyPb.NewTopologyServiceClient(conn)
+	_, err := topologyService.AddLink(ctx, &addLinkRequest)
+	if err != nil {
+		t.Errorf("Error while adding link: %v", err)
+	}
+
+	getTopolgyResponse, err := topologyService.GetTopology(ctx, &topologyPb.GetTopologyRequest{})
+	if err != nil {
+		t.Errorf("Error while getting topology: %v", err)
+	}
+
+	assert.Equal(t, 1, len(getTopolgyResponse.Toplogy.Links))
+	assert.Equal(t, "Link1", getTopolgyResponse.Toplogy.Links[0].Name)
+	assert.Equal(t, "Node1", getTopolgyResponse.Toplogy.Links[0].SourceNode.Name)
+	assert.Equal(t, "Node2", getTopolgyResponse.Toplogy.Links[0].TargetNode.Name)
+	assert.Equal(t, "Port1", getTopolgyResponse.Toplogy.Links[0].SourcePort.Name)
+	assert.Equal(t, "10.0.0.1", getTopolgyResponse.Toplogy.Links[0].SourcePort.Configuration.Ip)
+	assert.Equal(t, int64(24), getTopolgyResponse.Toplogy.Links[0].SourcePort.Configuration.PrefixLength)
+	assert.Equal(t, "Port2", getTopolgyResponse.Toplogy.Links[0].TargetPort.Name)
+	assert.Equal(t, "10.0.0.2", getTopolgyResponse.Toplogy.Links[0].TargetPort.Configuration.Ip)
+	assert.Equal(t, int64(24), getTopolgyResponse.Toplogy.Links[0].TargetPort.Configuration.PrefixLength)
+}
+
+// goSDN crashed due to validation errors in the topology service. If bug is fixed, uncomment and finish this test.
+//func TestCreateTopologyFailsValidation(t *testing.T) {
+//	defer integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig)
+//
+//	addLinkRequest := topologyPb.AddLinkRequest{
+//		Link: &topologyPb.Link{
+//			Name:       "Link1",
+//			SourceNode: &topologyPb.Node{Name: "Node1"},
+//			TargetNode: &topologyPb.Node{Name: "Node2"},
+//			SourcePort: &topologyPb.Port{Name: "Port1"},
+//			TargetPort: &topologyPb.Port{Name: "Port2"}},
+//	}
+//
+//	topologyService := topologyPb.NewTopologyServiceClient(conn)
+//	_, err := topologyService.AddLink(ctx, &addLinkRequest)
+//
+//	if err == nil {
+//		t.Errorf("Test expected an error, none received.")
+//	}
+//}
+
+// Test that creates a topology and then deletes it and checks that all topologies are deleted.
+
+// Can't delete topology because of bug in goSDN. If bug is fixed, uncomment and finish this test.
+//func TestCreateThenDeleteTopologyAndGetEmptyTopologies(t *testing.T) {
+//	defer integration_test_utils.ApplySDNConfig(conn, ctx, defaultSDNConfig)
+//
+//	addLinkRequest := topologyPb.AddLinkRequest{
+//		Link: &topologyPb.Link{
+//			Name:       "Link1",
+//			SourceNode: &topologyPb.Node{Name: "Node1"},
+//			TargetNode: &topologyPb.Node{Name: "Node2"},
+//			SourcePort: &topologyPb.Port{Name: "Port1",
+//				Configuration: &topologyPb.Configuration{
+//					Ip:           "10.0.0.1",
+//					PrefixLength: 24}},
+//			TargetPort: &topologyPb.Port{Name: "Port2",
+//				Configuration: &topologyPb.Configuration{
+//					Ip:           "10.0.0.2",
+//					PrefixLength: 24}}},
+//	}
+//
+//	topologyService := topologyPb.NewTopologyServiceClient(conn)
+//	_, err := topologyService.AddLink(ctx, &addLinkRequest)
+//	if err != nil {
+//		t.Errorf("Error while adding link: %v", err)
+//	}
+//
+//	getTopolgyResponse, err := topologyService.GetTopology(ctx, &topologyPb.GetTopologyRequest{})
+//	if err != nil {
+//		t.Errorf("Error while getting topology: %v", err)
+//	}
+//
+//	assert.Equal(t, 1, len(getTopolgyResponse.Toplogy.Links))
+//	assert.Equal(t, "Link1", getTopolgyResponse.Toplogy.Links[0].Name)
+//	assert.Equal(t, "Node1", getTopolgyResponse.Toplogy.Links[0].SourceNode.Name)
+//	assert.Equal(t, "Node2", getTopolgyResponse.Toplogy.Links[0].TargetNode.Name)
+//	assert.Equal(t, "Port1", getTopolgyResponse.Toplogy.Links[0].SourcePort.Name)
+//	assert.Equal(t, "10.0.0.1", getTopolgyResponse.Toplogy.Links[0].SourcePort.Configuration.Ip)
+//	assert.Equal(t, int64(24), getTopolgyResponse.Toplogy.Links[0].SourcePort.Configuration.PrefixLength)
+//	assert.Equal(t, "Port2", getTopolgyResponse.Toplogy.Links[0].TargetPort.Name)
+//	assert.Equal(t, "10.0.0.2", getTopolgyResponse.Toplogy.Links[0].TargetPort.Configuration.Ip)
+//	assert.Equal(t, int64(24), getTopolgyResponse.Toplogy.Links[0].TargetPort.Configuration.PrefixLength)
+//
+//	deleteLinkRequest := topologyPb.DeleteLinkRequest{Id: getTopolgyResponse.Toplogy.Links[0].Id}
+//	_, err = topologyService.DeleteLink(ctx, &deleteLinkRequest)
+//	if err != nil {
+//		t.Errorf("Error while deleting link: %v", err)
+//	}
+//	getTopologyRequest := &topologyPb.GetTopologyRequest{}
+//	getTopologyResponse, err := topologyService.GetTopology(ctx, getTopologyRequest)
+//	if err != nil {
+//		t.Errorf("Error while getting topologies: %v", err)
+//	}
+//
+//	assert.Equal(t, 0, len(getTopologyResponse.Toplogy.Links))
+//}
+//