Check if Wildfly Server is running with my app? - jboss

I would like to know how can I check if my Wildfly Server is running and the WebApp has been deployed?
Currently I check only if the server is running.
public static boolean checkServerAvailable() {
try {
String url = Constants.URL_APP + ":" + Constants.APPSERVER_PORT;
HttpURLConnection.setFollowRedirects(false);
// note : you may also need
// HttpURLConnection.setInstanceFollowRedirects(false)
HttpURLConnection con = (HttpURLConnection) new URL(url)
.openConnection();
con.setRequestMethod("HEAD");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
return true;
}
else
return false;
} catch (Exception e) {
return false;
}
}
But I need to know if the Wildfly server also my web app deployed successull.

To start with you could add your webapp url to the url you're creating above. Instead of connecting to, for example, http://localhost:8080/ and looking for a HTTP 200 response, you could connect to http://localhost:8080/yourApp and do the same. That implies that you have something at the root context to respond.
An arguably better solution would be to have a "heartbeat" or "status" service in your web application. This would be something like http://localhost:8080/yourApp/status. The method or service could just return a 200 implying that the service is up. But it could also really check that your application is healthy. For example, it could check available memory or make sure that the database is up or a multitude of other things. The code you show would just use the full URL of the status service.

You can use the management API provided by WildFly. The API is described here for different versions of WildFly.
For WildFly9 - See https://wildscribe.github.io/Wildfly/9.0.0.Final/deployment/index.html
You could use following URL to check the status of deployment. You do need a management user for authentication.
Standalone Mode:
http://localhost:9990/management/deployment/<deployment_name>
For domain mode:
http://localhost:9990/management/host/<host_name>/server/<serer_name>/deployment/<deployment_name>
Sample JSON response (assuming you deployed an EAR file with some sub-deployments):
{
"content": [{
"hash": {
"BYTES_VALUE": "2gH7ddtUxsbzBJEJ/z4T1jYERRU="
}
}],
"enabled": true,
"enabled-time": 1468861076770,
"enabled-timestamp": "2016-07-18 18:57:56,770 CEST",
"name": "myapplication.ear",
"owner": null,
"persistent": true,
"runtime-name": "myapplication.app.ear",
"subdeployment": {
"myapplication.impl.jar": null,
"myapplication.web.war": null
},
"subsystem": null
}
Sample request using curl:
curl --digest -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-resource", "include-runtime":"true", "address":["deployment","myapplication.app.ear"] }' -u user:password

I aws looking for something to check if wildfly is running, here I saw:
systemctl status wildfly
And also were so useful:
systemctl stop wildfly
systemctl restart wildfly
systemctl start wildfly

Related

Apache apisix routing configuration

I am new to apache APISIX, I want to configure the routing in the Apache APISIX gateway. First I have followed the APISIX official document. In that document, they have used "httpbin.org:80" for the upstream server. and it works for me, If I set the upstream new upstream server which is run in my localhost(127.0.0.1) it does not work for me. it throws a bad gateway error(502)
If anyone knows the answer to fix this issue, please let me know.
{
"methods": [
"GET"
],
"host": "example.com",
"uri": "/anything/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
The above routing configuration is working for me. Here is the API GATEWAY (http://127.0.0.1:9080/anything/*) routes the request to http://httpbin.org:80/anything/*)
{
"methods": [
"GET"
],
"host": "example.com",
"uri": "/anything/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:3001": 1
}
}
}
In the above configuration, I have configured the routing to service and that service is running on my local machine, and that port is 30001. Now if I call the API (http://127.0.0.1:9080/anything/*) it does not route my request to the server (http://127.0.0.1:3001/anything/*), instead it throws a bad gateway error.
const http = require('http')
const hostname = '127.0.0.1'
const port = 3001
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})
Here the above code is my backend server, which is running as an upstream server.
If you know the answer to debug the bad gateway exception, kindly let me know.
can you confirm which port you're using first because you're using 3001 but 30001 in your description; then try to access it directly instead of using Gateway to proxy it to check if it's accessible.
I have faced the exact issue.
I'm assuming you are deploying APISIX with docker-compose or docker (with is recommended in their official documentation).
The docker applications are running on a docker bridge network named apisix. This is why your localhost application is not reachable by APISIX.

How to Properly Set Permissions for a Custom Strapi Plugin

Strapi Version: 4.1.5
Operating System: Debian GNU/Linux 9
Database: PostgreSQL 13
Node Version: v14.16.0
NPM Version: 6.14.11
Yarn Version: v1.22.5
Hi everyone, I can’t seem to find consistent information on how to use permissions with a custom plugin in Strapi. I want to make an endpoint available to my front-end (Next.JS) application, but only when the front-end application has authenticated as a user and using the JWT that is returned from authenticating with Strapi. I keep getting a 401 returned.
Here’s what I’m doing:
I used this page to set up authentication in Strapi. I have a user created in Strapi, and from the front-end, I can authenticate and it returns a JWT token. When I set up collection types to only be accessible with the “authenticated” role, I can access those collection types in the api using this JWT token. So all of that works. The problem is that I can’t get this to work with my custom plugin, and I’m not sure why. I still get a 401 error instead.
Here’s how I set up the permissions:
Based on this page, I initially tried to leverage the isAuthenticated permission that the Users & Permissions plugin provides:
{
method: "GET",
path: "/progress",
handler: "memberProgress.getProgress",
config: {
policies: ['plugins::users-permissions.isAuthenticated']
},
},
Unfortunately, this did not work. The server raised an error, saying that this could not be found. So back on the document linked above, I decided to take the approach of creating my own gloabl permission. I created src/policies/is-authenticated.js with the following contents:
module.exports = (policyContext, config, { strapi }) => {
if (policyContext.state.user) { // if a session is open
// go to next policy or reach the controller's action
return true;
}
return false; // If you return nothing, Strapi considers you didn't want to block the request and will let it pass
};
Then, I modified my plugin’s route as follows:
{
method: "GET",
path: "/progress",
handler: "memberProgress.getProgress",
config: {
policies: ['global::is-authenticated']
},
},
This is all based on that document I linked to. Unfortunately, this still does not work. It seems to find the permission (server doesn’t raise an error about it), but when I try to access my plugin’s endpoint with the JWT token, I just get a 401 error.
Here is how I’m trying to access the endpoint on the front-end:
// VERIFIED, auth works and I get the expected jwt
const strapiAuth = await strapiApiAuth();
if ( strapiAuth && strapiAuth.hasOwnProperty("jwt") ) {
try {
const response = await axios.get(
`${process.env.STRAPI_BACKEND_URL}/member-progress/progress?year=2022&name=&pageSize=10&page=1`,
{
headers: {
Accept: "application/json",
Authorization: `Bearer ${strapiAuth.jwt}`
},
timeout: 500,
}
);
console.log(response);
} catch (error) {
// This is where I land with the 401 error
console.log(error);
}
}
Strapi check if you have a valid jwt by default with "authenticated" role, but you must mark the permission to your custom endpoint in "Settings→User & Permission Plugin→Roles" of admin panel also.

Read Nexus 2.x logs using REST

Is it possible to read the Nexus 2.14 log (the one you see in Administration -> Logging) per http access (REST)?
If not, are there other means to read it from an external program?
There's an option to download the logs from the Log tab in Nexus.
Once you have downloaded the file, your browser will capture the URL from where it was downloaded, which will be listed in the downloads section of your browser.
You can use the below methods to fetch the logs,
Fetching the logs using curl:
curl -u uname:pass http://nexusURL/nexus/service/siesta/logging/log
Fetching the logs in Node.js using the request module:
var request = require('request')
var opts = {
headers: { Authorization: "Basic YWRtaW46YWRtaW4=" }, //For admin:admin
uri: 'http://nexusURL/nexus/service/siesta/logging/log',
method: "GET"
}
request(opts,function(err, res, body){
console.log(body)
}
);
It seems that
http://localhost:8081/nexus/service/siesta/logging/log
gives you the recent log file (found by trial and error).

GET request using Azure app services and Intel Edison

I wanted to read data from an azure app service's easy tables using REST API to an Intel Edison. Before I did the same using Azure Mobile Services and my code was this. PS: I'm programming the device by the Arduino IDE.
void send_request()
{
Serial.println("\nconnecting...");
if (client.connect(server, 80)) {
// POST URI
sprintf(buffer, "GET /tables/%s HTTP/1.1", table_name);
client.println(buffer);
// Host header
sprintf(buffer, "Host: %s", server);
client.println(buffer);
// Azure Mobile Services application key
sprintf(buffer, "X-ZUMO-APPLICATION: %s", ams_key);
client.println(buffer);
// JSON content type
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(strlen(buffer));
// End of headers
client.println();
// Request body
client.println(buffer);
}
else {
Serial.println("connection failed");
}
}
where server name was "genesis-iot-control.azure-mobile.net";
but now authentication has changed and mobile service has been replaced by app service. How can I access them using REST API on Intel Edison?
I had followed this lead but with no solutions.
Any kind of help is appreciated.
The Application Key mechanism has been removed from Mobile Apps.
You'll need to implement-your-own-header check.
See this article for more:
https://github.com/Azure/azure-mobile-apps-net-server/wiki/Implementing-Application-Key
In essence, you send a X-YOUR-CUSTOM-HEADER: SeCreT= from your Edison and check its value against an Application Setting (defined in the Portal) in your Node/C# Mobile App backend code.
Yes, they should have kept the old mechanism going, disable it by default but allow us to turn it back on with an application setting.
An alternative to that would be to either get a Bearer token from Azure AD and use that with Authorization: Bearer ToKen= (but that's eventually going to expire anyway unless you also take care of refreshing it), or build another Web App (or API endpoint in your current one) that you send a secret to, goes out to Azure AD and hands you the Bearer token.
OR if you're really in for a very entertaining afternoon, do the OAuth dance from your Edison!
A curl sample here:
https://ahmetalpbalkan.com/blog/azure-rest-api-with-oauth2/
For a tiny 2KB memory device (like Arduino Uno), storing both Bearer token and refresh token in memory is already game over.
I'd be very interested to learn if anyone has a better/more efficient/more secure approach to do authentication from microcontrollers with Mobile Apps.
Example - using X-SECRET as your custom authentication header:
// Todoitem.js
var azureMobileApps = require('azure-mobile-apps');
// Create a new table definition
var table = azureMobileApps.table();
// Execute only if x-secret header matches our secret
table.read(function (context) {
// All header names are in lowercase in context.req.headers
console.info('Got x-secret header with value: ' +
context.req.headers['x-secret']);
if (context.req.headers['x-secret'] == process.env.SECRET) {
console.info('Secret matches value in App Settings.');
return context.execute();
}
});
// Removed CREATE, UPDATE, DELETE definitions for brevity.
// YOU NEED TO PROTECT THOSE METHODS AS WELL!
// Finally, export the table to the Azure Mobile Apps SDK - it can be
// read using the azureMobileApps.tables.import(path) method
module.exports = table;
Behavior as seen from curl (needless to say you should use HTTPS if your Edison can do that):
$ curl -s -i http://{mobileapp}.azurewebsites.net/tables/todoitem \
-H "ZUMO-API-VERSION: 2.0.0"
HTTP/1.1 404 Not Found
...
X-Powered-By: Express
{"error":"The item does not exist"}
$ curl -s -i http://{mobileapp}.azurewebsites.net/tables/todoitem \
-H "ZUMO-API-VERSION: 2.0.0" \
-H "X-SECRET: SeCr3T="
HTTP/1.1 200 OK
...
X-Powered-By: Express
[
{
"id": "40b996d6-ec7f-4188-a310-0f02808e7093",
"createdAt": "2016-08-31T11:30:11.955Z",
...
"Yo_node":"Sup"
}
]
Using App Service Editor (Monaco / Visual Studio Online Editor) to code and check output - https://{mobileapp}.scm.azurewebsites.net/dev

Rest assured with digest auth

I have a working spring-mvc application with rest services and some rest-assured tests which are fine :
#Test
public void createFoobarFromScratchReturns201(){
expect().statusCode(201).given()
.queryParam("foo", generateFoo())
.queryParam("bar", generateBar())
.when().post("/foo/bar/");
}
=> OK
Then I implemented a digest authentication. Everything is working well, now I have to log in to use my services :
curl http://localhost:8089/foo/bar
=> HTTP ERROR 401, Full authentication is required to access this resource
curl http://localhost:8089/foo/bar --digest -u user_test:password
=> HTTP 201, CREATED
But when I try to upgrade my tests with the most obvious function, I still have a 401 error :
#Test
public void createFoobarFromScratchReturns201(){
expect().statusCode(201).given()
.auth().digest("user_test", "password") // Digest added here
.queryParam("foo", generateFoo())
.queryParam("bar", generateBar())
.when().post("/foo/bar/");
}
=> Expected status code <201> doesn't match actual status code <401>
I found some clues with the preemptive() function, but it seems to be only implemented for basic :
// Returns an AuthenticatedScheme and stores it into the general configuration
RestAssured.authentication = preemptive().basic("user_test", "password");
// Try a similar thing, but it didn't work :
RestAssured.authentication = RestAssured.digest("user_test", "password");
Currently, I am trying to achieve two things :
I need to upgrade a couple of my tests to support digest
I need to amend the #Before of the rest of my tests suites (whose are not related to auth issues), to be already logged in.
Any ideas or documentation ?
Try enabling support for cookies in the HTTP client embedded inside Rest Assured with:
RestAssuredConfig config = new RestAssuredConfig().httpClient(new HttpClientConfig().setParam(ClientPNames.COOKIE_POLICY, CookiePolicy.BEST_MATCH));
expect().statusCode(201).given()
.auth().digest("user_test", "password") // Digest added here
.config(config)
.queryParam("foo", generateFoo())
.queryParam("bar", generateBar())
.when().post("/foo/bar/");
The HTTP client (and therefore Rest Assured) supports digest authentication and the configuration of RestAssured using the digest method works well.