diff --git a/src/api-engine/api/routes/network/serializers.py b/src/api-engine/api/routes/network/serializers.py index 03cd6df4e..7c70258ba 100644 --- a/src/api-engine/api/routes/network/serializers.py +++ b/src/api-engine/api/routes/network/serializers.py @@ -31,6 +31,10 @@ class NetworkQuery(serializers.Serializer): help_text=NetworkStatus.get_info("Network Status:", list_str=True), choices=NetworkStatus.to_choices(True), ) + class Meta: + model = Network + fields = ("page", "per_page", "name") + extra_kwargs = {"name": {"required": False}} class NetworkIDSerializer(serializers.Serializer): @@ -38,12 +42,18 @@ class NetworkIDSerializer(serializers.Serializer): class NetworkResponse(NetworkIDSerializer): - status = serializers.ChoiceField( - help_text=NetworkStatus.get_info("Network Status:", list_str=True), - choices=NetworkStatus.to_choices(True), - ) + id = serializers.UUIDField(help_text="ID of Network") + created_at = serializers.DateTimeField(help_text="Network create time") - updated_at = serializers.DateTimeField(help_text="Network update time") + + class Meta: + model = Network + fields = ("id", "name", "created_at") + extra_kwargs = { + "name": {"required": True}, + "created_at": {"required": True, "read_only": False}, + "id": {"required": True, "read_only": False}, + } class NetworkMemberSerializer(serializers.Serializer): @@ -56,20 +66,13 @@ class NetworkMemberSerializer(serializers.Serializer): class NetworkCreateBody(serializers.ModelSerializer): - method = serializers.ChoiceField( - help_text=NetworkCreateType.get_info( - "Network Create Types:", list_str=True - ), - choices=NetworkCreateType.to_choices(True), - ) class Meta: model = Network - fields = ("type", "version", "method") - extra_kwargs = { - "type": {"required": True}, - "version": {"required": True}, - } + fields = ("name", "consensus", "organizations") + extra_kwargs = {"name": {"required": True}, + "consensus": {"required": True}, + "organizations": {"required": True}} class NetworkMemberResponse(serializers.Serializer): diff --git a/src/api-engine/api/routes/network/views.py b/src/api-engine/api/routes/network/views.py index edcad9310..b26aca2f0 100644 --- a/src/api-engine/api/routes/network/views.py +++ b/src/api-engine/api/routes/network/views.py @@ -7,6 +7,8 @@ from rest_framework.decorators import action from rest_framework.response import Response from drf_yasg.utils import swagger_auto_schema +from django.core.paginator import Paginator +from django.core.exceptions import ObjectDoesNotExist from api.routes.network.serializers import ( NetworkQuery, NetworkListResponse, @@ -19,6 +21,8 @@ NetworkIDSerializer, ) from api.utils.common import with_common_response +from api.lib.configtxgen import ConfigTX, ConfigTxGen +from api.models import Network, Node, Organization LOG = logging.getLogger(__name__) @@ -32,10 +36,38 @@ class NetworkViewSet(viewsets.ViewSet): ) def list(self, request): """ - List Networks + List network - Filter networks with query parameters. + :param request: query parameter + :return: network list + :rtype: list """ + serializer = NetworkQuery(data=request.GET) + if serializer.is_valid(raise_exception=True): + page = serializer.validated_data.get("page", 1) + per_page = serializer.validated_data.get("per_page", 10) + name = serializer.validated_data.get("name") + parameters = {} + if name: + parameters.update({"name__icontains": name}) + networks = Network.objects.filter(**parameters) + p = Paginator(networks, per_page) + networks = p.page(page) + networks = [ + { + "id": str(network.id), + "name": network.name, + "created_at": network.created_at, + } + for network in networks + ] + response = NetworkListResponse( + data={"total": p.count, "data": networks} + ) + if response.is_valid(raise_exception=True): + return Response( + response.validated_data, status=status.HTTP_200_OK + ) return Response(data=[], status=status.HTTP_200_OK) @swagger_auto_schema( @@ -46,12 +78,48 @@ def list(self, request): ) def create(self, request): """ - New Network + Create Network - Create new network through internal nodes, - or import exists network outside + :param request: create parameter + :return: organization ID + :rtype: uuid """ - pass + serializer = NetworkCreateBody(data=request.data) + if serializer.is_valid(raise_exception=True): + name = serializer.validated_data.get("name") + consensus = serializer.validated_data.get("consensus") + organizations = serializer.validated_data.get("organizations") + + try: + Network.objects.get(name=name) + except ObjectDoesNotExist: + pass + orderers = [] + peers = [] + i = 0 + for organization in organizations: + org = Organization.objects.get(pk=organization) + orderers.append({"name": org.name, "hosts": []}) + peers.append({"name": org.name, "hosts": []}) + nodes = Node.objects.filter(org=org) + for node in nodes: + if node.type == "peer": + peers[i]["hosts"].append({"name": node.name, "port": node.urls.split(":")[2]}) + elif node.type == "orderer": + orderers[i]["hosts"].append({"name": node.name, "port": node.urls.split(":")[2]}) + i = i + 1 + + ConfigTX(name).create(consensus=consensus, orderers=orderers, peers=peers) + ConfigTxGen(name).genesis() + + network = Network(name=name, consensus=consensus, organizations=organizations) + network.save() + + response = NetworkIDSerializer(data=network.__dict__) + if response.is_valid(raise_exception=True): + return Response( + response.validated_data, status=status.HTTP_201_CREATED + ) @swagger_auto_schema(responses=with_common_response()) def retrieve(self, request, pk=None): @@ -62,6 +130,20 @@ def retrieve(self, request, pk=None): """ pass + @swagger_auto_schema( + responses=with_common_response( + {status.HTTP_204_NO_CONTENT: "No Content"} + ) + ) + def destroy(self, request, pk=None): + try: + network = Network.objects.get(pk=pk) + network.delete() + except ObjectDoesNotExist: + raise BaseException + + return Response(status=status.HTTP_204_NO_CONTENT) + @swagger_auto_schema( methods=["get"], responses=with_common_response(