66from rest_framework .decorators import action
77from rest_framework .permissions import IsAuthenticated
88import os
9- import tempfile , shutil , tarfile , json
9+ import tempfile
10+ import shutil
11+ import tarfile
12+ import json
1013
1114from drf_yasg .utils import swagger_auto_schema
1215from api .config import FABRIC_CHAINCODE_STORE
3538import hashlib
3639import logging
3740
41+
3842LOG = logging .getLogger (__name__ )
3943
44+
4045class ChainCodeViewSet (viewsets .ViewSet ):
4146 """Class represents Channel related operations."""
4247 permission_classes = [IsAuthenticated , ]
@@ -52,13 +57,19 @@ def _read_cc_pkg(self, pk, filename, ccpackage_path):
5257 meta_path = os .path .join (ccpackage_path , "metadata.json" )
5358 # extract metadata file
5459 with tarfile .open (os .path .join (ccpackage_path , filename )) as tared_file :
55- metadata_file = tared_file .getmember ("metadata.json" )
56- tared_file .extract (metadata_file , path = ccpackage_path )
57-
58- with open (meta_path , 'r' ) as f :
59- metadata = json .load (f )
60- language = metadata ["type" ]
61- label = metadata ["label" ]
60+ metadata_file = None
61+ for member in tared_file .getmembers ():
62+ if member .name .endswith ("metadata.json" ):
63+ metadata_file = member
64+ break
65+
66+ if metadata_file is not None :
67+ # Extract the metadata file
68+ metadata_content = tared_file .extractfile (
69+ metadata_file ).read ().decode ("utf-8" )
70+ metadata = json .loads (metadata_content )
71+ language = metadata ["type" ]
72+ label = metadata ["label" ]
6273
6374 if os .path .exists (meta_path ):
6475 os .remove (meta_path )
@@ -110,7 +121,10 @@ def list(self, request):
110121 ]
111122 response = ChaincodeListResponse (
112123 {"data" : chanincodes_list , "total" : chaincodes .count ()})
113- return Response (data = ok (response .data ), status = status .HTTP_200_OK )
124+ return Response (
125+ data = ok (
126+ response .data ),
127+ status = status .HTTP_200_OK )
114128 except Exception as e :
115129 return Response (
116130 err (e .args ), status = status .HTTP_400_BAD_REQUEST
@@ -144,22 +158,23 @@ def package(self, request):
144158 if member .name .endswith ("metadata.json" ):
145159 metadata_file = member
146160 break
147-
161+
148162 if metadata_file is not None :
149163 # Extract the metadata file
150- metadata_content = tar .extractfile (metadata_file ).read ().decode ("utf-8" )
164+ metadata_content = tar .extractfile (
165+ metadata_file ).read ().decode ("utf-8" )
151166 metadata = json .loads (metadata_content )
152167 label = metadata .get ("label" )
153168 else :
154169 return Response (
155- err ("Metadata file not found in the chaincode package." ), status = status . HTTP_400_BAD_REQUEST
156- )
170+ err ("Metadata file not found in the chaincode package." ),
171+ status = status . HTTP_400_BAD_REQUEST )
157172
158173 org = request .user .organization
159174 # qs = Node.objects.filter(type="peer", organization=org)
160175 # if not qs.exists():
161176 # return Response(
162- # err("at least 1 peer node is required for the chaincode package upload."),
177+ # err("at least 1 peer node is required for the chaincode package upload."),
163178 # status=status.HTTP_400_BAD_REQUEST
164179 # )
165180 # peer_node = qs.first()
@@ -168,7 +183,7 @@ def package(self, request):
168183 # return_code, content = peer_channel_cli.lifecycle_calculatepackageid(temp_cc_path)
169184 # if (return_code != 0):
170185 # return Response(
171- # err("calculate packageid failed for {}.".format(content)),
186+ # err("calculate packageid failed for {}.".format(content)),
172187 # status=status.HTTP_400_BAD_REQUEST
173188 # )
174189 # packageid = content.strip()
@@ -184,7 +199,7 @@ def package(self, request):
184199 cc = ChainCode .objects .filter (package_id = packageid )
185200 if cc .exists ():
186201 return Response (
187- err ("package with id {} already exists." .format (packageid )),
202+ err ("package with id {} already exists." .format (packageid )),
188203 status = status .HTTP_400_BAD_REQUEST
189204 )
190205
@@ -205,8 +220,9 @@ def package(self, request):
205220
206221 # start thread to read package meta info, update db
207222 try :
208- threading .Thread (target = self ._read_cc_pkg ,
209- args = (uuid , file .name , ccpackage_path )).start ()
223+ threading .Thread (
224+ target = self ._read_cc_pkg ,
225+ args = (uuid , file .name , ccpackage_path )).start ()
210226 except Exception as e :
211227 raise e
212228
@@ -229,6 +245,8 @@ def package(self, request):
229245 @action (detail = False , methods = ['post' ])
230246 def install (self , request ):
231247 chaincode_id = request .data .get ("id" )
248+ # Get the selected node ID from request
249+ node_id = request .data .get ("node" )
232250 try :
233251 cc_targz = ""
234252 file_path = os .path .join (FABRIC_CHAINCODE_STORE , chaincode_id )
@@ -237,16 +255,31 @@ def install(self, request):
237255 break
238256
239257 org = request .user .organization
240- qs = Node .objects .filter (type = "peer" , organization = org )
241- if not qs .exists ():
242- raise ResourceNotFound
243- peer_node = qs .first ()
258+
259+ # If node_id is provided, get that specific node
260+ if node_id :
261+ try :
262+ peer_node = Node .objects .get (
263+ id = node_id , type = "peer" , organization = org )
264+ except Node .DoesNotExist :
265+ return Response (
266+ err ("Selected peer node not found or not authorized." ),
267+ status = status .HTTP_404_NOT_FOUND
268+ )
269+ else :
270+ # Fallback to first peer if no node selected
271+ qs = Node .objects .filter (type = "peer" , organization = org )
272+ if not qs .exists ():
273+ raise ResourceNotFound
274+ peer_node = qs .first ()
244275
245276 envs = init_env_vars (peer_node , org )
246277 peer_channel_cli = PeerChainCode (** envs )
247278 res = peer_channel_cli .lifecycle_install (cc_targz )
248279 if res != 0 :
249- return Response (err ("install chaincode failed." ), status = status .HTTP_400_BAD_REQUEST )
280+ return Response (
281+ err ("install chaincode failed." ),
282+ status = status .HTTP_400_BAD_REQUEST )
250283 except Exception as e :
251284 return Response (
252285 err (e .args ), status = status .HTTP_400_BAD_REQUEST
0 commit comments