SAP HCP Java proxy servlet to mask a variable - javascript

Introduction
I have a SAP HANA Cloud Platform account. I have also deployed a Java application to the account and created a test servlet, which returns dummy data.
On the other side i have a SAP UI5 application which i develop on the WebIDE. I created also two destinations:
Destination "virtualTEST" is connected to a SAP Backend System (HANA Cloud Connector)
Destination "javaTEST" is connected to my Java servlet application
The neo-app.json is well configured and can obtain data from the test servlet (the dummy data) and data from the SAP Backend System (OData Gateway).
The problem
Now i want to pass variables to the SAP Backend System (virtualTEST) destination, which should not be visible in the frontend to avoid javascript manipulation.
My first thought
My first thought was that i create a new servlet which acts as proxy. In the SAPUI5 i call the servlet from javaTEST destination and pass the "hidden variables" like /testServlet?targetUrl=https://webide-xxx.hana.ondemand.com/sap/opu/odata/TEST_SRV/TEST?$filter=Var eq '{{MYVAR}}' and the Java application replaces {{MYVAR}} with my real variable. Then the target will be loaded (this is also a destination url to my SAPUI5 application). This does not work, i do not know why, but i think the proxy can not obtain data from the destination of an application.
Also, i think this is not the best solution. How can this be solved? Any ideas or best practices? Can destinations be used in Java application? :)

It is not really clear to me what you want to achieve. Of cause you can call destinations from Java.
<resource-ref>
<res-ref-name>myBackend</res-ref-name>
<res-type>com.sap.core.connectivity.api.http.HttpDestination</res-type>
</resource-ref>
import javax.naming.Context;
import javax.naming.InitialContext;
import com.sap.core.connectivity.api.http.HttpDestination;
...
// coding to lookup the destination "myBackend"
Context ctx = new InitialContext();
HttpDestination destination = (HttpDestination)
ctx.lookup("java:comp/env/myBackend");
// coding to call service "myService" on the system configured in the given destination
HttpClient createHttpClient = destination.createHttpClient();
HttpGet get = new HttpGet("myService");
HttpResponse resp = createHttpClient.execute(get);
from the official documentation. in the HttpGet you could set Params if you like.
In my opion your Backend should be so save you don't have to worry about Javascript manipulations, especially not for exposed OData services
Regards
Mathias

Related

Communication between JavaScript and WCF Service Library (WCF Test Client)

there is a web service (WCF Service Library) when I debug the web service project (in Visual Studio) "Test Client WCF" is launched (so I guess its hosted via the Test Client). I have a web service method called "Test" which returns string. When I "call" that method with the Test Client WCF - it works.
When I want to use browser as a client. I go to http://localhost:9001/Name/WebService/WebAPI and I see the web service (xml with some info about methods). And now I want to use JavaScript to call that Test method.
I created a client similar to this https://stackoverflow.com/a/11404133 and I replace the sr variable (SOAP request) with a request, which is in XML part of the Test method in the "Test Client WCF" and for url I chose http://localhost:9001/Name/WebService/WebAPI . I tried that JavaScript client, but I got some client error -
content-type 'text-xml' is invalid, server wanted
'application/soap+xml; charset=utf-8'
(unfortunately right now I can't get to the web service, so I don’t know a number of the error and exact message, but there was no other information, beside the content-type). So I changed the request header to 'application/soap+xml; charset=utf-8', but then I got error – that tells me:
The message cannot be processed at the receiver, due to an
AddressFilter mismatch at the EndpointDispatcher. Check that the
sender and receiver's EndpointAddresses agree
(Or something like that - I had to translated it to english)
I also tried the "JavaScript client" with an existing service, that I found on the internet and with text/xml content-type. And it works fine.
Please do you have any advice - how to call the Test method with JavaScript? Thanks.
The service invocated in Javascript is called Restful style service. WCF is able to create a Restful style service too. But we need to set up some kinds of additional configuration. The service is hosting in IIS express when we test the service in Visual Studio. It uses the default binding configuration to host the service(BasicHttpBinding), called SOAP web service. The universal way to invocate the service is taking advantage of using service proxy class, that is what the WCFTestClient do.
If we want to invocate the service by using JavaScript, here is a simple demo, wish it is useful to you. Please be aware that the project template is WCF Service Application instead of Service Library project.
https://stackoverflow.com/questions/56873239/how-to-fix-err-aborted-400-bad-request-error-with-jquery-call-to-c-sharp-wcf/56879896#56879896
Feel free to let me know if there is something I can help with.

how to invoke java adapter procedure from client side?

I have created java adapter in MobileFirst 7.0, My problem is how to invoke Java adapter from client side (js). I found Java adapter doesn't have procedures to call from client.
Thanks in Advance :)
How does your Java adapter look like? which environment are you testing this in?
Did you read the tutorial that explains how to call Java adapters in Hybrid applications?
See here: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-0/server-side-development/invoking-adapter-procedures-hybrid-client-applications/
In Java adapters, instead of "procedure name" you need to supply the #path you have set in your Java code.
WLResourceRequest
var resourceRequest = new WLResourceRequest(
"/adapters/RSSReader/getFeedsFiltered",
WLResourceRequest.GET
);
The WLResourceRequest class handles resource requests to MobileFirst
adapters or external resources.
The parameters for the constructor are:
request URL: To access an adapter within the same project, the URL
should be /adapters/AdapterName/procedureName.
To access resources outside of the project, use the full URL.
HTTP method: Most commonly WLResourceRequest.GET or
WLResourceRequest.POST timeout: optional, request timeout in
milliseconds
If you still have any more questions, check out this blogpost on getting started with java adapters.
https://developer.ibm.com/mobilefirstplatform/2015/03/24/getting-familiar-ibm-mobilefirst-platform-foundation-java-adapters/

Upload file using google cloud end points to google app engine application

I have an application on Google App Engine written in python, i am using this application as a server to my web application written in PHP which i am using as client to call my server side api on GAE using javascript end point.
I want to upload file from my web application to my GAE application using google cloud end points.I studied about blob store but it didn't help much.
Please suggest what should i do.
You have to use the Cloud Storage to store your files, instead of Blobstore.
Use GCS because:
Google is moving away from the blobstore
GCS offers more functionality like acl, folders, and more.
You can use filenames and a blobstore like serving url for images
You can create serving url's for non images
GCS is cheap and has a free default bucket
To using GCS, you have to use the https://cloud.google.com/appengine/docs/python/googlecloudstorageclient/
Here is an exemple in Java to use this API:
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename filename = new GcsFilename(CONSTANTES.BUCKETNAME, unique+".jpg");
GcsFileOptions options = new GcsFileOptions.Builder()
.mimeType("image/jpg")
.acl("public-read")
.build();
GcsOutputChannel writeChannel = gcsService.createOrReplace(filename, options);
EDIT: This is written (my mistake) as if you were on java. Feel free to use the analogous pattern for PHP on App Engine.
What the other user wrote about GCS answers the storage portion of your question - you should definitely use GCS - but as far as your idea of POSTing the form data to an endpoints function, this is definitely not advised. API calls should be little tiny pieces of data. An API should be like a paper airplane, lightly flying to your server to request some real data.
The way to have users upload files to GCS is to serve them a page with a file upload form (enctype="multipart/form-data") where the form action parameter is an upload URL generated to template the page in your servlet's doGet(HttpServletRequest req, HttpServletResponse resp) method using the GCS client library function createUploadUrl(). You can use it like this:
String uploadUrl = blobstoreService
.createUploadUrl("/upload",
UploadOptions.Builder.withGoogleStorageBucketName("my_bucket"));
In this manner you can obtain an upload URL for GCS that the user's file POST will go to. The route /upload is a route on your app that will be redirected once the upload is received. Any extra form parameters you add will still be visible to the request handler (a doPost() method on a servlet) which you define for that route.
With all of this info, you're ready to begin serving file upload forms to your users, without worrying about how this interacts with Cloud Endpoints. Use Endpoints to define API calls needed by your javascript/Android/iOS client, not for handling file uploads.

Wireing Breeze (with Angular) to an existing WCF Data Service

The Short
I have an existing WCF Data Service that I would like to wire up to use in an AngularJS SPA using Breeze.
Can anyone show a noobie level example of how to do that with out access to the actual database (just the OData Service)?
The Long
I have an existing WCF Data Service that is already in use by a WPF app.
I experimenting with web development and would like to wire up to that service using Breeze. In case it matters, I am using Angular (and am setting up via the HotTowel.Angular nuget package).
I have done a fair amount of Googling and I am stuck.
I can see two ways outlined from my searching:
The First
Make is to make a Breeze controller on the server side of my web app.
The problem I see with that is the metadata. From my limited understanding I need to tell breeze all the meta data of my WCF Data Service. I know how to get the meta from my WCF Data Service (the url + $Metadata), but I don't know how to tell this to Breeze.
The Second
This way is more vague in implementation. I got it from the accepted answer on this question: Breeze.js with WCF Data Service.
Basically the answer here does not seem to work. It relies on something called the entityModel that I cannot seem to find (I have an entityManager, but not an entityModel. And the entityManager does not have the properties that the entityModel is shown to have.
In the end I like the idea of the second method best. That way I can directly connect to my odata service with out needed my web app to have a "in-between" server component. But I would happily take anything that does not need entity framework to connect to my database.
I tried several variations of the second option, but I just can't seem to get it to work. I also tried the Breeze samples. It has one for OData, but it still relies on having Entity Framework hook up to the source database.
To to clearly summarize what I am asking: I am looking for a Breeze example that connects to an existing WCF Data Service.
We regret that you were mislead by that old StackOverflow answer which was way out of date and (therefore) incorrect. There is no longer a type called entityModel.
I updated the answer there and repeat here the same advice.
The recommended way to configure Breeze so that it talks to a standard OData source (such as a WCF OData service) is
breeze.config.initializeAdapterInstance('dataService', 'OData', true);
Here's how you might proceed with defining an EntityManager and querying the service:
// specify the absolute URL to the WCF service address
var serviceName = "http://localhost:9009/ODataService.svc";
var em = new breeze.EntityManager(serviceName);
var query = breeze.EntityQuery.from("Customers")
.where("CompanyName", "startsWith", "B")
.orderBy("City");
em.executeQuery(query).then(function(data) {
// process the data.results here.
});
There is some documentation on this subject here.
A Web API OData service differs from a WCF OData service in several respects. But you may still find value in the Angular Web API OData sample.

Breeze.js - re-target save to custom endpoint

I communicate with OData services by using Breeze.js and wanna be able to get and save data.
So there are two endpoints which should be used to get and save resources:
1. https://domain.com/smth/getdata
2. https://domain.com/smth/postdata
I created a manager which purpose is to get data, and send them back to server if needed:
var smthManager = new EntityManager(http://domain.com/smth/getdata);
After changing entities in smthManager I have to save them (by using endpoind 2). Investigating documentation I have found the next statement:
you can re-target a "save" to a custom server endpoint such as an
arbitrarily named action method on a separate
So here is the code to "re-target a save":
var so = new SaveOptions({ resourceName: "postdata" }); // also tried with resourceName: 'http://domain.com/smth/postdata'
myEntityManager.SaveChanges(null, so );
But after all these manipulations what can I see that request was sent to https://domain.com/smth/getdata/$batch
Breeze with a WebApi or WebApi2 service supports multiple server endpoints. Breeze with an OData service does not because the OData spec itself only supports a single $batch save for a service.
See http://www.odata.org/documentation/odata-v2-documentation/batch-processing/
Note that any Breeze WebApi or WebApi2 service is a superset of what can be provided directly from an OData service and is in general just as easy to expose your model from ( as long as you have a .NET server).

Categories

Resources