Beispiel #1
0
    def post():
        decoded = decode_token()
        github_url = request.form.get("github_url")
        if github_url is not None:
            files = GithubRead().get_files_github_url(github_url)
        else:
            files = request.files.getlist('manifest[]')
            filepaths = request.values.getlist('filePath[]')
            # At least one manifest file path should be present to analyse a stack
            if not filepaths:
                raise HTTPError(400, error="Error processing request. "
                                           "Please send a valid manifest file path.")
            if len(files) != len(filepaths):
                raise HTTPError(400, error="Error processing request. "
                                           "Number of manifests and filePaths must be the same.")

        # At least one manifest file should be present to analyse a stack
        if not files:
            raise HTTPError(400, error="Error processing request. "
                                       "Please upload a valid manifest files.")

        dt = datetime.datetime.now()
        origin = request.form.get('origin')
        request_id = uuid.uuid4().hex
        manifests = []
        ecosystem = None
        for index, manifest_file_raw in enumerate(files):
            if github_url is not None:
                filename = manifest_file_raw.get('filename', None)
                filepath = manifest_file_raw.get('filepath', None)
                content = manifest_file_raw.get('content')
            else:
                filename = manifest_file_raw.filename
                filepath = filepaths[index]
                content = manifest_file_raw.read().decode('utf-8')

            # check if manifest files with given name are supported
            manifest_descriptor = get_manifest_descriptor_by_filename(filename)
            if manifest_descriptor is None:
                raise HTTPError(400, error="Manifest file '{filename}' is not supported".format(
                    filename=filename))

            # In memory file to be passed as an API parameter to /appstack
            manifest_file = StringIO(content)

            # Check if the manifest is valid
            if not manifest_descriptor.validate(content):
                raise HTTPError(400, error="Error processing request. Please upload a valid "
                                           "manifest file '{filename}'".format(filename=filename))

            # appstack API call
            # Limitation: Currently, appstack can support only package.json
            #             The following condition is to be reworked
            appstack_id = ''
            if 'package.json' in filename:
                appstack_files = {'packagejson': manifest_file}
                url = current_app.config["BAYESIAN_ANALYTICS_URL"]
                endpoint = "{analytics_baseurl}/api/{version}/appstack".format(
                    analytics_baseurl=url,
                    version=ANALYTICS_API_VERSION)
                try:
                    response = requests.post(endpoint, files=appstack_files)
                except Exception as exc:
                    current_app.logger.warn("Analytics query: {}".format(exc))
                else:
                    if response.status_code == 200:
                        resp = response.json()
                        appstack_id = resp.get('appstack_id', '')
                    else:
                        current_app.logger.warn("{status}: {error}".format(
                            status=response.status_code,
                            error=response.content))

            # Record the response details for this manifest file
            manifest = {'filename': filename,
                        'content': content,
                        'ecosystem': manifest_descriptor.ecosystem,
                        'filepath': filepath}
            if appstack_id != '':
                manifest['appstack_id'] = appstack_id

            manifests.append(manifest)

        # Insert in a single commit. Gains - a) performance, b) avoid insert inconsistencies
        # for a single request
        try:
            req = StackAnalysisRequest(
                id=request_id,
                submitTime=str(dt),
                requestJson={'manifest': manifests},
                origin=origin
            )
            rdb.session.add(req)
            rdb.session.commit()
        except SQLAlchemyError as e:
            current_app.logger.exception('Failed to create new analysis request')
            raise HTTPError(500, "Error inserting log for request {t}".format(t=request_id)) from e

        try:
            data = {'api_name': 'stack_analyses',
                    'user_email': decoded.get('email', '*****@*****.**'),
                    'user_profile': decoded}
            args = {'external_request_id': request_id, 'ecosystem': ecosystem, 'data': data}
            server_run_flow('stackApiGraphV2Flow', args)
        except Exception as exc:
            # Just log the exception here for now
            current_app.logger.exception('Failed to schedule AggregatingMercatorTask for id {id}'
                                         .format(id=request_id))
            raise HTTPError(500, ("Error processing request {t}. manifest files "
                                  "could not be processed"
                                  .format(t=request_id))) from exc

        return {"status": "success", "submitted_at": str(dt), "id": str(request_id)}
    def post():
        """Handle the POST REST API call."""
        decoded = decode_token()
        github_url = request.form.get("github_url")
        if github_url is not None:
            files = GithubRead().get_files_github_url(github_url)
        else:
            files = request.files.getlist('manifest[]')
            filepaths = request.values.getlist('filePath[]')

            current_app.logger.info('%r' % files)
            current_app.logger.info('%r' % filepaths)

            # At least one manifest file path should be present to analyse a stack
            if not filepaths:
                raise HTTPError(400,
                                error="Error processing request. "
                                "Please send a valid manifest file path.")
            if len(files) != len(filepaths):
                raise HTTPError(
                    400,
                    error="Error processing request. "
                    "Number of manifests and filePaths must be the same.")

        # At least one manifest file should be present to analyse a stack
        if not files:
            raise HTTPError(400,
                            error="Error processing request. "
                            "Please upload a valid manifest files.")

        dt = datetime.datetime.now()
        request_id = uuid.uuid4().hex

        iso = datetime.datetime.utcnow().isoformat()

        manifests = []
        ecosystem = None
        for index, manifest_file_raw in enumerate(files):
            if github_url is not None:
                filename = manifest_file_raw.get('filename', None)
                filepath = manifest_file_raw.get('filepath', None)
                content = manifest_file_raw.get('content')
            else:
                filename = manifest_file_raw.filename
                filepath = filepaths[index]
                content = manifest_file_raw.read().decode('utf-8')

            # check if manifest files with given name are supported
            manifest_descriptor = get_manifest_descriptor_by_filename(filename)
            if manifest_descriptor is None:
                raise HTTPError(
                    400,
                    error="Manifest file '{filename}' is not supported".format(
                        filename=filename))

            # In memory file to be passed as an API parameter to /appstack
            manifest_file = StringIO(content)

            # Check if the manifest is valid
            if not manifest_descriptor.validate(content):
                raise HTTPError(
                    400,
                    error="Error processing request. Please upload a valid "
                    "manifest file '{filename}'".format(filename=filename))

            # Record the response details for this manifest file
            manifest = {
                'filename': filename,
                'content': content,
                'ecosystem': manifest_descriptor.ecosystem,
                'filepath': filepath
            }

            manifests.append(manifest)

        try:
            req = StackAnalysisRequest(
                id=request_id,
                submitTime=str(dt),
                requestJson={'manifest': manifests},
            )
            rdb.session.add(req)
            rdb.session.commit()
        except SQLAlchemyError as e:
            raise HTTPError(
                500, "Error inserting log for request {t}".format(
                    t=request_id)) from e

        data = {
            'api_name': 'stack_analyses',
            'user_email': decoded.get('email', '*****@*****.**'),
            'user_profile': decoded
        }
        args = {
            'external_request_id': request_id,
            'ecosystem': ecosystem,
            'data': data
        }

        try:
            api_url = current_app.config['F8_API_BACKBONE_HOST']

            d = DependencyFinder()
            deps = d.execute(args, rdb.session)
            deps['external_request_id'] = request_id

            _session.post('{}/api/v1/stack_aggregator'.format(api_url),
                          json=deps)
            _session.post('{}/api/v1/recommender'.format(api_url), json=deps)
        except Exception as exc:
            raise HTTPError(
                500, ("Could not process {t}.".format(t=request_id))) from exc

        return {
            "status": "success",
            "submitted_at": str(dt),
            "id": str(request_id)
        }