SapUI5 and Odata Service issue - odata

I am trying to consume Gateway OData Services in sapui5 app.
Metadata - /sap/opu/odata/SAP/ZUSER_MANAGE_SRV/$metadata as follows:
UserdataSet - /sap/opu/odata/SAP/ZUSER_MANAGE_SRV/UserdataSet as follows:
MY CODE
var oModel = new sap.ui.model.odata.ODataModel("http://Host:Port/sap/opu/odata/SAP/ZUSER_MANAGE_SRV", false,"USER","Password");
var app = new sap.m.App("myApp",{});
var oTable = new sap.m.Table("list1", {
growing: true,
growingThreshold: 200,
//mode: sap.m.ListMode.SingleSelect,
columns: [
new sap.m.Column({
header: new sap.m.Label({text: "ID"})
}),
new sap.m.Column({
header: new sap.m.Label({text: "First Name"})
}),
new sap.m.Column({
header: new sap.m.Label({text: "Last Name"})
})
],
items: {
path: "/UserdataSet",
template: new sap.m.ColumnListItem({
cells: [
new sap.m.Input({value: "{EUname}"}),
new sap.m.Input({value: "{EFirstname}"}),
new sap.m.Input({value: "{ELastname}"})
]
})
}
});
oTable.setModel(oModel);
var page1 = new sap.m.Page("page1",{
title: "App",
content: [oTable]
});
app.addPage(page1);
return app;
Getting error as - uncaught exception: [object Object].
Detailed Error:
Please help, whats wrong with my code?

Your OData service needs to be on the same server or needs to appear to be coming from the same server as your UI5 application. If it's not on the same server you should get Gateway to produce CORS headers.
Please find more info on CORS and how to get Gateway to produce these headers here: http://scn.sap.com/community/gateway/blog/2014/09/23/solve-cors-with-gateway-and-chrome

The Error is not very clear maybe chrome will show an more detailed error in this case.
If your application server and odata service are not from the same origin, the SOP (same origin policy) restricts this action.
Two pages have the same origin if the protocol, port and host are the same for both pages.
see https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy for more details.
you can start chrome with --disable-web-security flag:
In CMD:
C:/<path to chrome app>/chrome.exe --disable-web-security
!!! ONLY FOR DEVELOPMENT REASONS !!!

Related

KrakenD: Trouble to upload file though gateway via POST request using Form-Data

Describe what are you trying to do
In one of my applications, I need to upload a file to my server from my angular website.
Basically, to do this I use the FormData object to which append several informations, like the file name, and others.
To send the file itself I will append to the FormData an fs.readStream().
Then I post this via axios to my server endpoint.
Exemple of code (postman request using form-data):
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('avatar', fs.createReadStream('/home/file.mp3'));
data.append('title', 'test');
data.append('description', 'test');
var config = {
method: 'post',
url: 'localhost:8080/upload-file',
headers: {
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Concerning the server, it is developed in node.js and I use the "multer" middleware to retrieve the file.
Exemple of an endpoint code :
import {Response, Request} from "express";
public static async UploadFile(req: Request, res: Response): Promise<any> { }
Without krakend gateway, it's works perfectly and I can then retrieve the file in my endpoint so that: req.file
The others informations sent like "title", "description" are in req.body
Using krakend, I get all the information on the server side except the file, in the request, I only find the req.body and not the req.file
So my question is, how come krakend is not sending the file data to the backend and what would be the solution in order to send file via POST request a FormData to krakend ?
Your configuration file
The content of your krakend.json:
{
"version": 3,
...
{
"endpoint": "/upload",
"method": "POST",
"output_encoding": "no-op",
"backend": [
{
"method": "POST",
"encoding": "no-op",
"url_pattern": "/upload-file",
"host": [
"http://containername:8080"
]
}
]
}
}
I tried to use the different "no-op" annotations but nothing works, I have the impression that krakend does not interpret my file upload
Commands used
How did you start the software?
I use docker-compose:
krakend:
container_name: 'Gateway'
image: devopsfaith/krakend
volumes:
- ./KrakenD/dev/:/etc/krakend
ports:
- "8080:8080"
- "1234:1234"
- "8090:8090"
links:
- some containers
- ...
restart: always
network_mode: bridge
Logs
I don't have a specific log, only my backend which returns a 400 code as it can't find the file information in the request.
for those who are going through the same problem. Please note that postman was the cause of the problem for me, KrakenD does support sending bodies as multipart/form-data, so don't forget to let the headers through as needed.
The problem is that when passing through postman, I can't explain but the file is badly sent to krakenD. Use Insomnia, or a simple Curl to do your tests.
Maybe you have to include "Content-Type" at input-headers.
"input_headers": [
"Authorization",
"Content-Type"
],
Here you can find more info about it.

Nestjs with Neo4j graphQL library causing RangeError: Maximum call stack size exceeded

I am trying to learn a new concept for myself - Graph databases.
I also decided to try out GraphQL with it.
Learning two new technologies... What possibly could go wrong??!?!?
I created a wee apollo+neo4j+neo4j-graphql library project and it works. I could make custom resolvers, the data saves to the DB...everything works great.
So I decided to add a structure to this wee project and what is better than Angular structure, right? So.. . I found Nest JS.
My question is... How do you marry NestJs with Neo4j-graphQL library?
I just keep getting:
RangeError: Maximum call stack size exceeded
With this code
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("neo4j", "Qwertyui1!")
);
const neoSchema = new Neo4jGraphQL({
typeDefs,
driver,
config: {
jwt: {
secret: "secret"
}
}
});
let graphSchema: GraphQLSchema = neoSchema.schema;
console.error(graphSchema);
#Module({
imports: [
GraphQLModule.forRoot({
playground: false,
plugins: [ApolloServerPluginLandingPageLocalDefault()],
debug: false,
disableHealthCheck: true,
// typePaths: ['./models/*.graphql'],
definitions: {
path: null
},
schema: graphSchema
})
],
Here is the source code:
https://github.com/mcgri/neo4jWithNestjs

Getting "oModel.read is not a function" error

While performing Read operation on V4 ODatamodel I'm getting an error saying
oModel.read is not a function
Code
Error
Please let me know how to correct if I did something wrong.
This error is expected.
read method does not exist in oData Model V4.
See below:
read is not a function in V4
However, you can do the same thing with oData V2(recommended approach for working with oData as V4 has still some features missing)
Restrictions with oData V4
oData V2 vs oData V4
Nevertheless, if you need to bind the response items later with a table, you can
do it as:
var oModel = new sap.ui.model.odata.v4.ODataModel({
groupId: "$auto",
serviceUrl: "url",
synchronizationMode: "None",
operationMode: "Server"
}),
oSettings = new sap.ui.model.json.JSONModel({
bOnlyLarge: false,
bFilterGermany: false
});
var oTable = new sap.ui.table.Table({
columns: [{
label: "ProductName",
template: new sap.m.Text({
text: "{Country}"
}),
sortProperty: "ProductName"
}]
});
oTable.setModel(oModel);
oTable.bindRows({
path: "/Products"
});
var oModel = new sap.ui.model.odata.v4.ODataModel({
/* send requests directly. Use $auto for batch request wich will be send automatically on before rendering */
groupId : "$direct",
/* I'll just quote the API documentary:
Controls synchronization between different bindings which refer to the same data for the case data changes in one binding.
Must be set to 'None' which means bindings are not synchronized at all; all other values are not supported and lead to an error.
*/
synchronizationMode : "None",
/*
Root URL of the service to request data from.
*/
serviceUrl : "http://services.odata.org/TripPinRESTierService/",
/*
optional. Group ID that is used for update requests. If no update group ID is specified, mParameters.groupId is used.:
updateGroupId : "$direct"
*/
});

How to cache everything but content using sw-precache

I'm using sw-precache in a jekyll website to add offline capabilities with the following configuration:
gulp.task('generate-service-worker', function(cb) {
var path = require('path');
var swPrecache = require('sw-precache');
var rootDir = '_site';
var packageJson = require('./package.json');
swPrecache.write('./service-worker.js', {
staticFileGlobs: [rootDir + '/**/*.{html,css,png,jpg,gif,svg}', rootDir + '/js/*'],
stripPrefix: rootDir + '/',
runtimeCaching: [{
urlPattern: /\/$/,
handler: 'networkOnly'
}],
handleFetch: argv.cacheAssets || false,
maximumFileSizeToCacheInBytes: 10485760, // 10 mb
cacheId: packageJson.name + '-v' + packageJson.version
}, cb);
});
The problem is that, when I change content in the website (for example, text in a blog post, or some text from the index page) the changes won't be shown until the new serviceworker version has been installed and the browser has been refreshed, which of course, is the expected behaviour of cacheFirst.
What I want is to make the request to the index of the site always network first, which is what I'm trying here:
runtimeCaching: [{
urlPattern: /\/$/,
handler: 'networkFirst'
}]
But this isn't working, the index is always getting fetch from the serviceworker and not from network, how can I accomplish this?
My problem is that I was including the actual page contents for precache: '/**/*.{html,css,png,jpg,gif,svg}'.
Excluding the html files works as expected:
'/**/*.{css,png,jpg,gif,svg}'
Change the url pattern to
urlPattern: "'/'"
This is a exact match pattern. Your index will match to this and nothing else.
The solution for this is, treat your index.html as dynamic content.
Change you sw webpack config to
new SWPrecacheWebpackPlugin({
cacheId: 'yourcacheid',
filename: 'service-worker.js',
staticFileGlobs: [
'dist/**/*.{js,css}'
],
minify: true,
stripPrefix: 'dist/',
runtimeCaching: [{
urlPattern: /\/$/,
handler: 'networkFirst'
}]
})
Remove your index.html from staticFileGlobs and add you root index to runtime caching.
Then look at your cache storage. You will see something like $$$toolbox-cache$$$https://your-domain.com as a new cache item. Inspect that and you can see your index cached there.

oauth2orize sample returns AuthorizationError: not authorized

I've downloaded the oauth2orize provider code example and the sample oauth client suggested in the docs and I'm getting the following error:
500 AuthorizationError: not authorized at validated
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/middleware/authorization.js:131:36)
at
/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/oauth2.js:180:14
at Object.exports.findByClientId
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/db/clients.js:24:10)
at exports.authorization.res.render.transactionID
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/oauth2.js:174:16)
at
/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/middleware/authorization.js:167:9 at pass
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/server.js:262:26)
at pass
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/server.js:280:9)
at pass
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/server.js:271:11)
at Server._parse
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/server.js:285:5)
at authorization
(/Users/trevorallred/projects/pics/node-soa/oauth2orize/examples/all-grants/node_modules/oauth2orize/lib/middleware/authorization.js:118:12)
I'm running the client here: http://localhost:3002/
I click the link to "Connect with example-oauth2orize"
It redirects me to the provider: http://localhost:3000/login
After logging in with "bob" I'm sent to this error page.
The only modifications I've made are to oauth-config.js in the example client.
'use strict';
module.exports = {
provider: {
protocol: "http",
host: "localhost:3000",
profileUrl: "/api/userinfo"
},
consumer: {
protocol: "http",
host: "localhost:3002"
}
};
I tried modifying oauth-consumer-config.js after I saw this bug report but it didn't seem to change any behavior.
module.exports = {
name: 'Example Consumer App'
, icon: 'http://example.com/icon_64.png'
, clientId: 'trevorclient'
, clientSecret: 'kasdfasdfoq34t134tg109gqerg1gjc'
};
Try updating your oauth-consumer-config.js file to this:
module.exports = {
name: 'Example Consumer App'
, icon: 'http://localhost:3000/icon_64.png'
, clientId: 'abc123'
, clientSecret: 'ssh-secret'
};
The problem is that the all-grants example doesn't actually use a DB, but a flat file for illustration purposes. If you navigation to db/clients.js in the all-grants project, you'll see the clients listed there that are allowed to connect via OAuth.

Resources