can we connect to public api endpoint instead of local host using dredd tool? - dredd

I tried to use a public end point(eg:api.openweathermap.org/data/2.5/weather?lat=35&lon=139) instead of the local host while configuring dredd and ran the command to run the tool.But I am not able to connect to the end point through dredd. It is throwing Error:getaddrINFO EAI_AGAIN .
But when I tried to connect to the endpoint using post man .I am able to connect successfully

There is no difference in calling a local or remote endpoint.
Some remote endpoints have some sort of authorization requirements.
This an example of Dredd calling external endpoint:
dredd.yml configuration file fragment
...
blueprint: doc/api.md
# endpoint: 'http://api-srv:5000'
endpoint: https://private-da275-notes69.apiary-mock.com
As you see, the only change is the endpoint on Dredd configuration file (created using Dredd init).
But, as I mention, sometimes you'll need to provide authorization through the header or query string parameter.
Dreed has hooks that allow you to change things before each transaction, for instance:
You'd like to add the apikey parameter in each URL before executing the request. This code can handle that.
hook.js
// Writing Dredd Hooks In Node.js
// Ref: http://dredd.org/en/latest/hooks-nodejs.html
var hooks = require('hooks');
hooks.beforeEach(function(transaction) {
hooks.log('before each');
// add query parameter to each transaction here
let paramToAdd = 'api-key=23456';
if (transaction.fullPath.indexOf('?') > -1)
transaction.fullPath += '&' + paramToAdd;
else
transaction.fullPath += '?' + paramToAdd;
hooks.log('before each fullpath: ' + transaction.fullPath);
});
Code at Github gist
Save this hook file anywhere in your project an than run Dredd passing the hook file.
dredd --hookfiles=./hoock.js
That's it, after execution the log will show the actual URL used in the request.
info: Configuration './dredd.yml' found, ignoring other arguments.
2018-06-25T16:57:13.243Z - info: Beginning Dredd testing...
2018-06-25T16:57:13.249Z - info: Found Hookfiles: 0=/api/scripts/dredd-hoock.js
2018-06-25T16:57:13.263Z - hook: before each
2018-06-25T16:57:13.264Z - hook: before each fullpath: /notes?api-key=23456
"/notes?api-key=23456"
2018-06-25T16:57:16.095Z - pass: GET (200) /notes duration: 2829ms
2018-06-25T16:57:16.096Z - hook: before each
2018-06-25T16:57:16.096Z - hook: before each fullpath: /notes?api-key=23456
"/notes?api-key=23456"
2018-06-25T16:57:16.788Z - pass: POST (201) /notes duration: 691ms
2018-06-25T16:57:16.788Z - hook: before each
2018-06-25T16:57:16.789Z - hook: before each fullpath: /notes/abcd1234?api-key=23456
"/notes/abcd1234?api-key=23456"
2018-06-25T16:57:17.113Z - pass: GET (200) /notes/abcd1234 duration: 323ms
2018-06-25T16:57:17.114Z - hook: before each
2018-06-25T16:57:17.114Z - hook: before each fullpath: /notes/abcd1234?api-key=23456
"/notes/abcd1234?api-key=23456"
2018-06-25T16:57:17.353Z - pass: DELETE (204) /notes/abcd1234 duration: 238ms
2018-06-25T16:57:17.354Z - hook: before each
2018-06-25T16:57:17.354Z - hook: before each fullpath: /notes/abcd1234?api-key=23456
"/notes/abcd1234?api-key=23456"
2018-06-25T16:57:17.614Z - pass: PUT (200) /notes/abcd1234 duration: 259ms
2018-06-25T16:57:17.615Z - complete: 5 passing, 0 failing, 0 errors, 0 skipped, 5 total
2018-06-25T16:57:17.616Z - complete: Tests took 4372ms

Related

Google Cloud Function works in emulator but errs on deploy to Firebase: Unexpected token p in JSON at position 1

I have a cloud function that is meant to delete a post with its subcollection of comments. It properly deletes the post in the emulator. However, when I try to deploy the cloud function to Firebase the following error occurs:
i functions: updating Node.js 16 function
recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in
the user code. Error message:
Error: please examine your function logs to see the error cause:
https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs.
Additional troubleshooting documentation can be found at
https://cloud.google.com/functions/docs/troubleshooting#logging.
Functions deploy had errors with the following functions:
recursiveDelete(us-central1)
As instructed, I checked the error in the log in Google Cloud I found:
SyntaxError: Unexpected token p in JSON at position 1
at .JSON.parse
at .parse (
/layers/google.nodejs.functions-framework/functions-framework/node_modules/body-parser/lib/types/json.js:89
)
This is the function:
const functions = require("firebase-functions");
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
admin.initializeApp();
/**
* Initiate a recursive delete of documents at a given path.
* #param {string} data.path the document or collection path to delete.
*/
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall(async (data, context) => {
const path = data[0].path;
console.log(`Running cloud function recursiveDelete on ${path}`);
await firebase_tools.firestore
.delete(path, {
project: process.env.GCP_PROJECT,
recursive: true,
yes: true,
token: '...',
force: true
});
return {
path: path
};
});
This is how I'm calling it:
static Future<void> delete(String ref) async {
if (FirebaseAuth.instance.currentUser == null) {
throw Exception('Must be logged in');
}
await FirebaseFunctions.instance
.httpsCallable('recursiveDelete')
.call([{'path': 'posts/$ref'}])
.then((value) => logger("Post deleted: ${value.data}"))
.catchError((error) => logger.error("Failed to delete post: $error"));
}
In the emulator, deletion works fine and the output is:
I/flutter (26907): [Post] [INFO] Post deleted: {path:
posts/Gk4TeWEgZmm0QUcaqTrk}
So, what's wrong with it?
Full stack-trace:
=== Deploying to 'sightings-dev'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔ functions: required API cloudfunctions.googleapis.com is enabled
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ artifactregistry: required API artifactregistry.googleapis.com is enabled
i functions: preparing codebase default for deployment
i functions: preparing functions directory for uploading...
i functions: packaged /Users/strijdhaftig/sightings/frontend/flutter/sightings/functions (55.13 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation.
Functions deploy had errors with the following functions:
recursiveDelete(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions
Having trouble? Try again or contact support with contents of firebase-debug.log

Path variables in Apache Camel rest route

I would like to use path variables in my REST route URL in the following way:
rest().post("/companies/{companyId}/branches/branchId={branchId}");
The companyId can be properly retrieved as header, however, "branchId={branchId}" is treated as literal string. Therefore request to:
/companies/100/branches/branchId=200 - will return 404 not found.
but
/companies/100/branches/branchId={branchId} - will enter the route.
I would like to use branchId as header, in the same way as companyId, without having to change the structure of the URL.
Every path or query parameter can be received through the headers in Apache Camel. You can retrieve the headers with using the simple expression;
${header.your-header}
So you can retrieve the parameters as below;
parameter
simple expression
companyId
${header.companyId}
branchId
${header.branchId}
Here is a working Route example that I've made for you;
package com.bzdgn.camelso.route;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.rest.RestBindingMode;
public class RestEndpointRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
rest()
.post("/companies/{companyId}/branches/{branchId}")
.consumes("text/plain")
.produces("text/plain")
.to("direct:handle-post");
from("direct:handle-post")
.id("post-route")
.log("Received Body: ${body}")
.log("Company Id: ${header.companyId}")
.log("Branch Id: ${header.branchId}")
.setBody(simple("CompanyId = ${header.companyId} \nBranchId = ${header.branchId}"))
.convertBodyTo(String.class);
restConfiguration()
.component("netty-http")
.host("localhost")
.port("8080")
.bindingMode(RestBindingMode.auto);
}
}
The logs will be as below if you send a HTTP Post Request to the designated URL;
2021-05-28 21:13:30 INFO HttpServerBootstrapFactory:53 - BootstrapFactory on port 8080 is using bootstrap configuration: [NettyServerBootstrapConfiguration{protocol='http', host='localhost', port=8080, broadcast=false, sendBufferSize=65536, receiveBufferSize=65536, receiveBufferSizePredictor=0, workerCount=0, bossCount=1, keepAlive=true, tcpNoDelay=true, reuseAddress=true, connectTimeout=10000, backlog=0, serverInitializerFactory=org.apache.camel.component.netty.http.HttpServerInitializerFactory#ae3540e, nettyServerBootstrapFactory=null, options=null, ssl=false, sslHandler=null, sslContextParameters='null', needClientAuth=false, enabledProtocols='TLSv1,TLSv1.1,TLSv1.2, keyStoreFile=null, trustStoreFile=null, keyStoreResource='null', trustStoreResource='null', keyStoreFormat='JKS', securityProvider='SunX509', passphrase='null', bossGroup=null, workerGroup=null, networkInterface='null', reconnect='true', reconnectInterval='10000'}]
2021-05-28 21:13:30 INFO NettyComponent:164 - Creating shared NettyConsumerExecutorGroup with 17 threads
2021-05-28 21:13:31 INFO SingleTCPNettyServerBootstrapFactory:182 - ServerBootstrap binding to localhost:8080
2021-05-28 21:13:33 INFO NettyConsumer:77 - Netty consumer bound to: localhost:8080
2021-05-28 21:13:33 INFO AbstractCamelContext:2983 - Routes startup summary (total:2 started:2)
2021-05-28 21:13:33 INFO AbstractCamelContext:2988 - Started post-route (direct://handle-post)
2021-05-28 21:13:33 INFO AbstractCamelContext:2988 - Started route1 (rest://post:/companies/%7BcompanyId%7D/branches/%7BbranchId%7D)
2021-05-28 21:13:33 INFO AbstractCamelContext:3000 - Apache Camel 3.10.0 (camel-1) started in 3s337ms (build:93ms init:274ms start:2s970ms)
2021-05-28 21:13:35 INFO post-route:166 - Received Body: Example text body here
2021-05-28 21:13:35 INFO post-route:166 - Company Id: my-custom-company
2021-05-28 21:13:35 INFO post-route:166 - Branch Id: my-custom-branch-id
And you can test it via postman like this. The request, and the headers listed in the below images, and do not forget to add "Content Type: text/plain", because that's defined in the route that it will consume and produce "text/plain".

K6 Get reqeust result in error against specific endpoint URL

I am new to K6 and is trying to use the tool to perform a Get request by verifying an API.
When the script is executed I get a warning that terminates the scrip. As far as my understanding is that this error is somewhat related to Go (if I have understood it correctly).
The result that I want to achieve is to be able to execute the Get request to the endpoint URL, but would appreciate any kind of feedback if I have done any incorrectly or should try an other approach.
Script:
import http from "k6/http";
import { check } from "k6";
export default function () {
var url =
"https://endpoint.example.to.cloud/api/reports/v1/SMOKETESTC6KP6NWX";
var headerParam = {
headers: {
"Content-Type": "application/json",
},
};
const response = http.get(url, headerParam);
check(response, {
"Response status reciving a 200 response ": (r) => r.status === 200,
});
let body = JSON.parse(response.body);
}
Output:
WARN[0000] Request Failed error="Get \"https://endpoint.example.to.cloud/api/reports/v1/SMOKETESTC6KP6NWX\": x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0"
Changing URL endpoint:
If i change the URL endpoint (mockup url) like below, there will be no errors:
...
var url = "https://run.mocky.io/v3/16fa8113-57e0-4e47-99b9-b5c55da93d71";
...
Updated solution to run this locally:
In order to run this locally i had to add the certification and key:
Example:
export let options = {
...
tlsAuth: [
{
cert: open(`${__ENV.Certificate}`),
key: open(`${__ENV.Key}`),
},
],
};
In addition populate the execute command with --insecure-skip-tls-verify
Example:
k6 run -e Certificate=/home/cert/example_certification.crt -e Key=/home/cert/certification/example_key.key -e example.js --insecure-skip-tls-verify
k6 is written in Go, and the latest versions of Go have a breaking change in how they handle X.509 certificates: https://golang.org/doc/go1.15#commonname
As it says in the error message, you can temporarily allow the old behavior by setting a GODEBUG=x509ignoreCN=0 environment variable, but that will likely stop working in a few months with Go 1.17. Using the insecureSkipTLSVerify k6 option might also work, I haven't checked, but as the name implies, that stops any TLS verification and is insecure.
So the real solution is to re-generate your server-side certificate properly.

Ejabberd - ejabberd_auth_external:failure:103 External authentication program failed when calling 'check_password'

I already have a schema of users with authentication-key and wanted to do authentication via that. I tried implementing authentication via sql but due to different structure of my schema I was getting error and so I implemented external-authentication method. The technologies and OS used in my application are :
Node.JS
Ejabberd as XMPP server
MySQL Database
React-Native (Front-End)
OS - Ubuntu 18.04
I implemented the external authentication configuration as mentioned in https://docs.ejabberd.im/admin/configuration/#external-script and took php script https://www.ejabberd.im/files/efiles/check_mysql.php.txt as an example. But I am getting the below mentioned error in error.log. In ejabberd.yml I have done following configuration.
...
host_config:
"example.org.co":
auth_method: [external]
extauth_program: "/usr/local/etc/ejabberd/JabberAuth.class.php"
auth_use_cache: false
...
Also, is there any external auth javascript script?
Here is the error.log and ejabberd.log as mentioned below
error.log
2019-03-19 07:19:16.814 [error]
<0.524.0>#ejabberd_auth_external:failure:103 External authentication
program failed when calling 'check_password' for admin#example.org.co:
disconnected
ejabberd.log
2019-03-19 07:19:16.811 [debug] <0.524.0>#ejabberd_http:init:151 S:
[{[<<"api">>],mod_http_api},{[<<"admin">>],ejabberd_web_admin}]
2019-03-19 07:19:16.811 [debug]
<0.524.0>#ejabberd_http:process_header:307 (#Port<0.13811>) http
query: 'POST' <<"/api/register">>
2019-03-19 07:19:16.811 [debug]
<0.524.0>#ejabberd_http:process:394 [<<"api">>,<<"register">>] matches
[<<"api">>]
2019-03-19 07:19:16.811 [info]
<0.364.0>#ejabberd_listener:accept:238 (<0.524.0>) Accepted connection
::ffff:ip -> ::ffff:ip
2019-03-19 07:19:16.814 [info]
<0.524.0>#mod_http_api:log:548 API call register
[{<<"user">>,<<"test">>},{<<"host">>,<<"example.org.co">>},{<<"password">>,<<"test">>}]
from ::ffff:ip
2019-03-19 07:19:16.814 [error]
<0.524.0>#ejabberd_auth_external:failure:103 External authentication
program failed when calling 'check_password' for admin#example.org.co:
disconnected
2019-03-19 07:19:16.814 [debug]
<0.524.0>#mod_http_api:extract_auth:171 Invalid auth data:
{error,invalid_auth}
Any help regarding this topic will be appreciated.
1) Your config about the auth_method looks good.
2) Here is a python script I've used and upgraded to make an external authentication for ejabberd.
#!/usr/bin/python
import sys
from struct import *
import os
def openAuth(args):
(user, server, password) = args
# Implement your interactions with your service / database
# Return True or False
return True
def openIsuser(args):
(user, server) = args
# Implement your interactions with your service / database
# Return True or False
return True
def loop():
switcher = {
"auth": openAuth,
"isuser": openIsuser,
"setpass": lambda(none): True,
"tryregister": lambda(none): False,
"removeuser": lambda(none): False,
"removeuser3": lambda(none): False,
}
data = from_ejabberd()
to_ejabberd(switcher.get(data[0], lambda(none): False)(data[1:]))
loop()
def from_ejabberd():
input_length = sys.stdin.read(2)
(size,) = unpack('>h', input_length)
return sys.stdin.read(size).split(':')
def to_ejabberd(result):
if result:
sys.stdout.write('\x00\x02\x00\x01')
else:
sys.stdout.write('\x00\x02\x00\x00')
sys.stdout.flush()
if __name__ == "__main__":
try:
loop()
except error:
pass
I didn't created the communication with Ejabberd from_ejabberd() and to_ejabberd(), and unfortunately can't find back the sources.

Apiary Error when invoking API

I get the following error on ApiaryWe are sorry, but the API call failed.
My host is defined as
FORMAT: 1A
HOST: https://test.mynetwork.com/
GET CALL IS DEFINED AS
data urn [models/v2/files/{urn}/data{?guid}]
GET [GET]
Parameters
urn (required, string, ttt)...design urn.
guid (optional, string,067e6162-3b6f-4ae2-a171-2470b63dfe02)...filter by guid.
Response 200 (application/vnd.api+json)
Body
data
{
"version": "1.0",
}
When i invoke this , i get error . Any inputs
I have edited your API Blueprint as follows:
FORMAT: 1A
HOST: https://test.mynetwork.com
# Test API
This is a test API
## data urn [/models/v2/files/{urn}/data{?guid}]
+ Parameters
+ urn: `ttt` (required, string) - design urn
+ guid: `067e6162-3b6f-4ae2-a171-2470b63dfe02` (optional, string) - filter by guid
### test [GET]
+ Response 200 (application/vnd.api+json)
{
"version": "1.0"
}
You can find tutorials here: https://help.apiary.io/
Also not sure what you mean "invoke" the API - are you calling the mock server or are you hitting your own server through Apiary.
Happy to help further via the support option in Apiary itself or email us on support [at] apiary.io.