One of my Microservice [MS1] checks another Microservice [MS2] at startup, if MS2 is running or not. If MS2 is running MS1 will start else fails to start.
But currently I am running MS2 on my local machine which takes a huge amount of RAM ans slow down my machine.
Is there any mechanism so that when MS1 starts and look-up for MS2 it seems that MS2 is running without actually running real MS2?
Update :
Let's assume MS2 is running on localhost:1234 and now MS1 will connect to it using REST.
You can have a look at WireMock which is a simulator of HTTP API so it will be suitable for local development. When using it you will be able to mimic a microservice as if it was running as a standalone microservice on given host and port.
You can run it both as a standalone process and as a part of your spring application.
Option 1 - configuring standalone wiremock server :
Download Wiremock Standalone jar
Run standalone server on localhost with port 1234 :
java -jar wiremock-standalone-2.24.0.jar --port 1234
Configure your MS1 microservice to use localhost:1234 as your MS2 host.
Mock your MS2(mocked with wiremock) endpoint with some response :
curl -X POST --data '{ "request": { "url": "/yourendpoint", "method": "GET" }, "response": { "status": 200, "body": "Response" }}' http://localhost:1234/__admin/mappings/new
Here we make a mock that when you hit on your mocked server on /yourendpoint with HTTP GET you will receive text Response as response.
Now when you hit with GET on localhost:1234/yourendpoint you get your mocked response :
curl http://localhost:1234/yourendpoint
Response
Full example can be found at Wiremock Standalone docs
Option 2 - configuring WireMock server in your Spring app :
Add WireMock dependency to your project (watch out to add it not only to test scope)
Create a Spring bean used to set up your server :
#Component
public class CustomMicroserviceMock {
private WireMockServer wireMockServer;
public CustomMicroserviceMock() {
wireMockServer = new WireMockServer(options().port(1234));
wireMockServer.stubFor(get(urlEqualTo("/yourendpoint"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("Response")));
wireMockServer.start();
}
#PreDestroy
void preDestroy() {
wireMockServer.stop();
}
}
When we hit localhost:1234/yourendpoint we get response : Response
This is just a POC how it could look like but it works in both cases.
I recommend using WireMock as a standalone service in your local machine, or if you
are familiar with docker you can check the wiremock docker image :
https://hub.docker.com/r/rodolpheche/wiremock/
I'm using it for my development and testing, it's really a strong stubbing solution :)
Best of luck
Related
I have a backend application that is running on weblogic server. It is running on http://localhost:7000. This application has to be called with http://localhost:7000 then after verification it checks if the application schema is on https or not. If its not then it asks you to redirect to https://localhost:7001. The HTTPS configuration is enabled on weblogic server
WEBLOGIC SSL CONFIGURATION
So far everything running on same domain meaning the application is full fledge with java backend and angular js embedded frontend. So everything running on weblogic server.
Now we are in the process of migrating from angular js to angular. Now angular is running on http://localhost:4200. So I have created a proxy for HTTP call
{
"/api": {
"target": " http://127.0.01:7000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
And started server like so:
ng serve --proxy-config proxy.conf.json -o
server started on 4200 and creates proxy on http://127.0.01:7000/api
I have also created ssl proxy for HTTPS call
{
"/api": {
"target": "https://127.0.01:7001",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
Also started server like so on different port
ng serve --proxy-config proxy.ssl.conf.json –-port 4400
server started on 4400 and creates proxy on https://127.0.01:7001/api
Now I make the first call to backend url http://127.0.01:7000/api/permission
It calls through as http://localhost:4200/api/permission
It goes through filter and does some processing then it checks if call is through http or https if not then asks to redirect to https://localhost:7001/api/permission with some status code.
So in angular inside interceptor I check for the status, if status is for redirect, I redirect the url to
https://127.0.01:7001/api/permission
using
window.location.href=”https://localhost:4400/api/permission”
don’t be confuse because it calls like https://localhost:4400 and concat with backend url which is /api/permission.
Angular folks must be aware of that.
But I get a 504 error gateway timeout on chrome dev tools console
On cmd where I have started the ng server I get this
Error occurred while trying to proxy request /api/permission from localhost:4400 to https://127.0.01:7001 (ECONNRESET) (https ://nodejs.org/api/errors.html#errors_common_system_errors)
I am dead sure it’s a SSL issue but I just don’t know how to fix this.
I have done a lot research on this. I am frustrated, I have spent more than enough time to find a solution for this. I cant basically move pass this till its converted from http to https because rest of the uri calls must be made on https.
I found a link
How to send an HTTPS request from an Angular front-end to a server secured with a self signed certificate?
I think solution number one made sense
Add the self-signed certificate to the trusted store on the server where the angular app runs. (But in your case u cant do this because u got no access to the gitpages trusted store.
But I cant say for sure.
Any help please. I would really appreciate that. I am pretty much stuck at this point.
Cheers
This should work:
#Injectable()
export class httpsInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(req.url);
const secureReq = req.clone({
url: req.url.replace('http://', 'https://')
});
return next.handle(secureReq);
}
}
you must create an interceptor and import it in the module inside provider,
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true } ]
Sorry I am a bit late to answer. But the exact answer to my problem was PKI which is mutual authentication configured on weblogic and the way its done is you need to deploy your angular app on weblogic to kick in mutual authentication. There are several videos out their on how to deploy angular app on weblogic if someone looking to learn as well as how to configure mutual authentication on weblogic. Cheers
We have a Java web application at http://ourapp.com hosted at Heroku and the frontend of the app cannot connect to the WebSocket endpoint (endpoint) running in a Heroku dyno. We have tried these URIs:
ws://ourapp.com/endpoint
ws://ourapp.com:80/endpoint
ws://ourapp.com:8080/endpoint
ws://ourapp.com:8084/endpoint
ws://ourapp.com:443/endpoint
wss://ourapp.com/endpoint
wss://ourapp.com:80/endpoint
wss://ourapp.com:8080/endpoint
wss://ourapp.com:8084/endpoint
wss://ourapp.com:443/endpoint
None of the above open a connection. What are we missing here?
PS: I have set up a test ground: http://vakuutustiedot-dev.herokuapp.com/websocket.test.html (the URI is PROTOCOL:vakuutustiedot-dev.herokuapp.com:PORT/trial)
The target app runs in a Heroku Apache Tomcat 8.5.38.
What comes to the port number, I am not sure how to get one.
Perhaps you have missed adding the support of WebSockets to Heroku, like in this answer (https://stackoverflow.com/a/50002416/11197115)?
Maybe you should try configuring the proxy attribute of devServer. This attribute is used when the frontend app and backend api are not running on the same host. Perhaps the below setting might solve your problem.
module.exports = {
devServer: {
proxy: 'ws://ourapp.com:8080/endpoint'
}
}
For more info see the docs: https://cli.vuejs.org/config/#devserver
My Issue/Setup
I'm trying to build a stand-alone spring boot admin application which all our instances (in a private VPC- behind a network load balancer) can register with.
But my spring boot application itself runs inside a docker container, so hostname and ip-address always defaults to the container hostname and container ip-address.
And spring-boot admin fails with
`Request failed with status code 502`
Connection refused: /1XX.17.0.2:8840
because it cannot find actual hosts with the hostname or the IP addres.
What i tried
I had the set up working with below (one instance),
`spring.boot.admin.client.instance.service-base-url`
But cannot use this for multiple clients as i cannot specify a comma separated value.
Moreover, since there can be n number of instance at any time i do not want to use the below property.
`spring.boot.admin.client.instance.service-base-url`
So i took the suggestion to omit spring.boot.admin.client.instance.service-base-url on spring-boot-admin git hub page and issues section and used below instead
`spring.boot.admin.client.instance.prefer-ip=true`
But Since my applications are running inside a docker container,
spring boot clients register itself with container id/ip-address as the hostname/ip-address.
I also tried the "--net=admin-network","--name client" parameters in my AWS beanstalk file
"containerDefinitions": [
{
"name": "cloudy-email",
"image": "xxx.dkr.ecr.us-east-2.amazonaws.com/sba-admin-repo:xx_2019-04-24_14.36_e9aax8710",
"command": [ "--net=admin-network","--name client"],
"Update": "true",
How can i overcome this issue?
Any pointers/references would be much appreciated.
You can make docker run in the host network using the --network host option to the docker run command. This will make the container assume the same IP address of the host VM. Also, check if you are exposing the admin port through Docker and the host firewall (security groups).
More info: https://docs.docker.com/network/host/
My goal (background info)
I want to develop a java microservice on cumulocity. It should be able to do the following:
I would send "112233" to the microservice as follows:
https://myTenant.cumulocity.com/service/my-application-name/decode?data=112233
The microservice should then split the data into "11" for the first measurement and "22" for the second measurement etc. These measurements would be POSTed to cumulocity.
My problem
I am now stuck on getting the Hello, microservice tutorial to work. I can't deploy the microservice (zip file) to cumulocity.
"error":"security/Forbidden","info":"https://www.cumulocity.com/guides/reference-guide/#error_reporting","message":"Access is denied"} (I am an admin user.)
I also tried to upload the zip file via the website, this created a HOSTED application instead of a MICROSERVICE. Uploading my zip via a POST request to a HOSTED application actually works (which I obviously don't need).
I suspect that I get the "access denied" error cause cumulocity thinks that I upload a HOSTED application to a MICROSERVICE.
What I've done so far
Code side
I downloaded the hello-world-microservice example from the cumulocity bitbucket development branch. (This code is not available on the default branch).
I changed the cumulocity versions to 9.3.0, only this version seems to exist.
The HelloWorldMain.java is unedited
This is my cumulocity.json manifest file: (the roles make no difference)
{
"apiVersion":"1",
"type":"MICROSERVICE",
"version":"#project.version#",
"availability":"PRIVATE",
"provider":{
"name":"Cumulocity GmbH"
},
"isolation":"MULTI_TENANT",
"requiredRoles":[
"ROLE_APPLICATION_MANAGEMENT_ADMIN",
"ROLE_MEASUREMENT_ADMIN",
"ROLE_INVENTORY_ADMIN"
],
"roles":[
"ROLE_APPLICATION_MANAGEMENT_ADMIN",
"ROLE_MEASUREMENT_ADMIN",
"ROLE_INVENTORY_ADMIN"
],
"livenessProbe":{
"httpGet":{
"path":"/health",
"port":80
},
"initialDelaySeconds":15,
"periodSeconds":10
},
"readinessProbe":{
"httpGet":{
"path":"/health",
"port":80
}
}
}
This is my application.properties file
application.name=my-application-name
server.port=80
C8Y.baseURL=https://myTenant.cumulocity.com
C8Y.bootstrap.tenant=myTenant
C8Y.bootstrap.user=servicebootstrap_my-application-name
C8Y.bootstrap.password={SECRET_BOOTSTRAP_PASSW}
C8Y.user={MY_USERNAME}
C8Y.password={SECRET_PASSW}
C8Y.bootstrap.register=true
C8Y.microservice.isolation=MULTI_TENANT
C8Y.bootstrap.initialDelay=10000
Cumulocity side
I successfully created a microservice application,
GET https://myTenant.cumulocity.com/application/applications/5886 returns:
{
"availability":"PRIVATE",
"id":"5886",
"key":"my-application-key",
"manifest":{
"imports":[
],
"noAppSwitcher":true
},
"name":"my-application-name",
"owner":{
"self":"https://myTenant.cumulocity.com/tenant/tenants/myTenant",
"tenant":{
"id":"myTenant"
}
},
"requiredRoles":[
"ROLE_APPLICATION_MANAGEMENT_ADMIN",
"ROLE_MEASUREMENT_ADMIN",
"ROLE_INVENTORY_ADMIN"
],
"roles":[
"ROLE_APPLICATION_MANAGEMENT_ADMIN",
"ROLE_MEASUREMENT_ADMIN",
"ROLE_INVENTORY_ADMIN"
],
"self":"https://myTenant.cumulocity.com/application/applications/5886",
"type":"MICROSERVICE"
}
I also successfully subscribed to this application.
When I try to upload the zip file to cumulocity, I get this error:
"error":"security/Forbidden","info":"https://www.cumulocity.com/guides/reference-guide/#error_reporting","message":"Access is denied"}
(Uploading to a HOSTED type application works fine, but I don't want that.)
note: I also tried to use the microservice deploy script, this gave the same result as doing everything manually.
Trying to run it locally
Since I couldn't get it to work on the cumulocity platform, I tried to run it locally via docker. I ran it with this command:
docker run -e "C8Y_MICROSERVICE_ISOLATION=MULTI_TENANT" 10aa0b73ddb3
note: I had to add the "C8Y_MICROSERVICE_ISOLATION=MULTI_TENANT" environment variable. if I didn't add this, I'd get credential/permission issues. This seems weird to me, since all other info is read from the application.properties file except for this one.
I have no errors when running this image on a local docker.
According to the Hello, microservice tutorial, I should be able to request curl -H "Authorization: {AUTHORIZATION}" https://myTenant.cumulocity.com/service/my-application-name/hello?who=me
This returns:
{"error":"microservice/Not Found","info":"https://www.cumulocity.com/guides/reference-guide/#error_reporting","message":"Microservice my-application-name not found."}
Back to the questions
Has anyone else had difficulties with setting up a microservice on cumulocity?
Is there something I'm totally overseeing?
The microservice hosting needs to be assigned to your tenant otherwise it won't work and the API in that case will return forbidden. So it might be that it is no issue with your user but that your tenant has the feature not activated.
I am trying to build a chat application.
+Server : I use java websocket to create an endpoint. Here is my endpoint:
#ServerEndpoint("/server")
public class ChatServer {
//My code is ok ! Tested in localhost
}
+Client : I use java swing to create GUI. In my localhost, I use this URL :
ws://localhost:8080/ChatServer-1.0/server
to connect to Server Endpoint and my app run successful.
-> I have deployed my server endpoint to Heroku
My Heroku Server Endpoint
How can my client to connect to server endpoint ?
I have tried to use:
wss://jp-chatting-server.herokuapp.com/server
But it gives a 404 code.
I think you have used instruction for webapp-runner. I'm afraid this solution will not work for websockets. It is because support of websocket is not implemented yeat. Issue with websocket in webapp-runner. I see one of the options in using Tomcat 7 and it's custom implementation. Like in this example.