New feature: Code changes for project support
[osm/SO.git] / rwlaunchpad / plugins / rwpkgmgr / rift / tasklets / rwpkgmgr / rpc.py
1 #
2 # Copyright 2016 RIFT.IO Inc
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16 # Author(s): Varun Prasad
17 # Creation Date: 09/25/2016
18 #
19
20 import abc
21 import asyncio
22 import tempfile
23
24 from gi.repository import (
25 RwDts as rwdts,
26 RwPkgMgmtYang)
27 import rift.tasklets
28 import rift.mano.dts as mano_dts
29
30 from . import downloader as pkg_downloader
31
32 # Shortcuts
33 RPC_PKG_ENDPOINT = RwPkgMgmtYang.YangOutput_RwPkgMgmt_GetPackageEndpoint
34 RPC_SCHEMA_ENDPOINT = RwPkgMgmtYang.YangOutput_RwPkgMgmt_GetPackageSchema
35 RPC_PACKAGE_ADD_ENDPOINT = RwPkgMgmtYang.YangOutput_RwPkgMgmt_PackageFileAdd
36 RPC_PACKAGE_DELETE_ENDPOINT = RwPkgMgmtYang.YangOutput_RwPkgMgmt_PackageFileDelete
37
38
39 class EndpointDiscoveryRpcHandler(mano_dts.AbstractRpcHandler):
40 """RPC handler to generate the endpoint for the Package manager."""
41
42 def __init__(self, log, dts, loop, proxy):
43 """
44 Args:
45 proxy: Any impl of .proxy.AbstractPackageManagerProxy
46 """
47 super().__init__(log, dts, loop)
48 self.proxy = proxy
49
50 @property
51 def xpath(self):
52 return "/rw-pkg-mgmt:get-package-endpoint"
53
54 @asyncio.coroutine
55 def callback(self, ks_path, msg):
56 """Forwards the request to proxy.
57 """
58 url = yield from self.proxy.endpoint(
59 msg.package_type,
60 msg.package_id)
61
62 rpc_op = RPC_PKG_ENDPOINT.from_dict({"endpoint": url})
63
64 return rpc_op
65
66
67 class SchemaRpcHandler(mano_dts.AbstractRpcHandler):
68 """RPC handler to generate the schema for the packages.
69 """
70 def __init__(self, log, dts, loop, proxy):
71 """
72 Args:
73 proxy: Any impl of .proxy.AbstractPackageManagerProxy
74 """
75 super().__init__(log, dts, loop)
76 self.proxy = proxy
77
78 @property
79 def xpath(self):
80 return "/rw-pkg-mgmt:get-package-schema"
81
82 @asyncio.coroutine
83 def callback(self, ks_path, msg):
84
85 package_type = msg.package_type.lower()
86 schema = yield from self.proxy.schema(msg.package_type)
87
88 rpc_op = RPC_SCHEMA_ENDPOINT()
89 for dirname in schema:
90 rpc_op.schema.append(dirname)
91
92 return rpc_op
93
94
95 class PackageOperationsRpcHandler(mano_dts.AbstractRpcHandler):
96 """File add RPC
97
98 Steps:
99 1. For a request, we schedule a download in the background
100 2. We register the downloader to a publisher to push out the download status
101 Note: The publisher starts the download automatically.
102 3. Return a tracking ID for the client to monitor the entire status
103
104 """
105 def __init__(self, log, dts, loop, proxy, tasklet):
106 """
107 Args:
108 proxy: Any impl of .proxy.AbstractPackageManagerProxy
109 publisher: Instance of tasklet to find the DownloadStatusPublisher
110 for a specific project
111 """
112 super().__init__(log, dts, loop)
113 self.proxy = proxy
114 self.tasklet = tasklet
115
116 @property
117 def xpath(self):
118 return "/rw-pkg-mgmt:package-file-add"
119
120 def get_publisher(self, msg):
121 try:
122 proj = self.tasklet.projects[msg.project_name]
123 except Exception as e:
124 err = "Project or project name not found {}: {}". \
125 format(msg.as_dict(), e)
126 self.log.error (err)
127 raise Exception (err)
128
129 return proj.job_handler
130
131 @asyncio.coroutine
132 def callback(self, ks_path, msg):
133 publisher = self.get_publisher(msg)
134
135 if not msg.external_url:
136 # For now we will only support External URL download
137 raise Exception ("No download URL provided")
138
139 # Create a tmp file to download the url
140 # We first store the data in temp and post download finish
141 # we move the file to actual location.
142 _, filename = tempfile.mkstemp()
143
144 auth = None
145 if msg.username is not None:
146 auth = (msg.username, msg.password)
147
148 url_downloader = pkg_downloader.PackageFileDownloader.from_rpc_input(
149 msg,
150 auth=auth,
151 file_obj=filename,
152 proxy=self.proxy,
153 log=self.log)
154
155 download_id = yield from publisher.register_downloader(url_downloader)
156
157 rpc_op = RPC_PACKAGE_ADD_ENDPOINT.from_dict({"task_id": download_id})
158
159 return rpc_op
160
161
162 class PackageDeleteOperationsRpcHandler(mano_dts.AbstractRpcHandler):
163 def __init__(self, log, dts, loop, proxy):
164 """
165 Args:
166 proxy: Any impl of .proxy.AbstractPackageManagerProxy
167 """
168 super().__init__(log, dts, loop)
169 self.proxy = proxy
170
171 @property
172 def xpath(self):
173 return "/rw-pkg-mgmt:package-file-delete"
174
175 @asyncio.coroutine
176 def callback(self, ks_path, msg):
177
178 rpc_op = RPC_PACKAGE_DELETE_ENDPOINT.from_dict({"status": str(True)})
179
180 try:
181 self.proxy.package_file_delete(
182 msg.package_type,
183 msg.package_id,
184 msg.package_path)
185 except Exception as e:
186 self.log.exception(e)
187 rpc_op.status = str(False)
188 rpc_op.error_trace = str(e)
189
190 return rpc_op