I am facing an issue in CQN functionality.
Oracledb: version 19.0.0.0.0(19c)
version_full 19.18.0.0.0
Nodejs: 18.12.1
instant client: 21.3
below is my code
function callThisFun(message) {
const printMessage = JSON.stringify(message?.tables)
console.log(printMessage)
logger.info(`db change info: ${printMessage}`)
}
const options = {
clientInitiated: true,
callback: callThisFun,
events: true,
sql: `Select * from MASTER_TABLE_CRUD_DEMO`,
}
let connection = await oracledb.getConnection(pool);
connection.subscribe(tableName, options);
My callback is not getting triggered.
I tried with updating node oracledb to latest version but still not my cqn logic not working
Related
I am running a graphql server using serverless offline and trying to connect to the server with Aollo Studio. The weirdest bug is that it was connecting properly a week back and now the exact same server is not connecting. The same thing I have deployed on the AWS and Aollo Studio is able to connect to the deployed server. Any idea what could be the reason for it?
Environment
I am on Macbook m1 pro.
Node Version 15.6
As you can in the config file I have started a playground as well on this path http://localhost:3000/dev/playground which I am able to access but this playground is also not connecting the server.
One thing which I have observed is my local network IP URL like http://192.168.1.3:3000/dev/playground is also not working when I am trying to visit so maybe some kind of network issue might be there.
But when I run something like a React App I am able to access it on this http://192.168.1.3:3000
My serverless.yml looks like below
service: serverless-graphql-rds
frameworkVersion: "3.8.0"
provider:
name: aws
runtime: nodejs14.x
stage: ${env:PROVIDER_STAGE}
region: ${env:REGION}
environment:
JWT_SECRET: ${env:JWT_SECRET}
DATABASE_URL: ${env:DATABASE_URL}
REDIRECT_TO_DASHBOARD: ${env:REDIRECT_TO_DASHBOARD}
HUB_SPOT_CLIENT_ID: ${env:HUB_SPOT_CLIENT_ID}
HUB_SPOT_CLIENT_SECRET: ${env:HUB_SPOT_CLIENT_SECRET}
HUB_SPOT_REDIRECT_URI: ${env:HUB_SPOT_REDIRECT_URI}
plugins:
- serverless-plugin-typescript
- serverless-offline
package:
patterns:
- "migrations/**"
- "**.js"
- "config"
custom:
serverless-offline:
httpPort: ${env:httpPort, 3000}
lambdaPort: ${env:lambdaPort, 3002}
serverless-plugin-typescript:
tsConfigFileLocation: "./tsconfig.json"
functions:
graphql:
handler: server.handler
events:
- http:
path: graphql
method: post
cors: true
playground:
handler: server.playgroundHandler
events:
- http:
path: playground
method: get
cors: true
oauth-callback:
handler: ./rest-apis-handlers/oauth-callback.handler
events:
- http:
path: oauth-callback
method: get
cors: true
And the file server.ts looks like below which contains the handler function
import { ApolloError, ApolloServer } from "apollo-server-lambda";
import lambdaPlayground from "graphql-playground-middleware-lambda";
import { verifyToken } from "./common/jwt";
import { useContext } from "./core/context";
import resolvers from "./graphql/resolvers";
import typeDefs from "./graphql/schema";
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ event, context, express }) => {
const auth = express.req.headers["authorization"] as string;
if (auth) {
const [_, token] = auth.split("Bearer ");
try {
const user = verifyToken(token);
if (user) {
return useContext({
type: "user",
properties: {
...user,
},
});
} else {
throw new ApolloError("Not authenticated", "UNAUTHENTICATED");
}
} catch (ex) {}
}
return useContext({
type: "public",
});
},
});
export const handler = server.createHandler({});
// for local endpointURL is /graphql and for prod it is /stage/graphql
export const playgroundHandler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
return lambdaPlayground({
endpoint: process.env.REACT_APP_GRAPHQL_ENDPOINT,
})(event, context, callback);
};
After struggling for 3 days today I finally figured it out.
As I am using the serverless-offline package to run the local graphql server and due to the node version it requires less than 15. Here is the details discussion on it.
So just downgrade the node version to anything < 15 and it will work.
I am using nodejs to listen to my table's data change using oracle CQN.
I do have the grant permission and vice versa connection from my DB server to my production server. The below code is working fine from a DB server and APP Hosting server
function myCallback(message) {
console.log(`myCallback:: Listened new data insertion`);
runFunction();
}
const options = {
callback: myCallback,
sql: `SELECT * FROM ${schemaName}.${tableName} where STATUS=0`,
qos : oracledb.SUBSCR_QOS_ROWIDS,
clientInitiated: true,
};
async function listener() {
//Create Connection Pool
try {
await oracledb.createPool({
user: `${userName}`,
password: `${userPass}`,
connectString: `${connString}`,
externalAuth: false,
events: true,
poolMax: parseInt(`${poolMax}`),
poolMin: parseInt(`${poolMin}`),
// poolTimeout: parseInt(`${poolTimeout}`),
// queueMax: parseInt(`${queueMax}`),
// queueTimeout: parseInt(`${queueTimeout}`),
});
//Create Connection
const connection = await oracledb.getConnection();
await connection.subscribe('mysub', options);
console.log("App is Listening ");
} catch (e) {
console.log("Error on Listening" + e);
}
}
But while changing to a new DB hosting server I don't receive the change notification. I have used the query to check whether the event registration is working or not.
SELECT * from USER_CHANGE_NOTIFICATION_REGS
I do get many regid which means the event registration is working fine.
So why the CallBack function is not working.
Thanks.
So I added a lambda function category using the amplify CLI, in order to query data from the GSI(Global secondary Index) I created using the #key directive in the graphql schema. Whenever I try mocking the function locally using the amplify mock function <functionName> the callback function of the query keeps on returning null. The function can be seen below
const AWS = require("aws-sdk");
const db = new AWS.DynamoDB.DocumentClient({
region: process.env.REGION,
apiVersion: "2012-08-10",
});
const params = {
// ProjectionExpression: ["province", "gender", "updatedAt", "createdAt"],
ExpressionAttributeValues: {
":provinceVal": "Sichuan",
},
IndexName: "RegistreesByProvince",
KeyConditionExpression: "province = :provinceVal",
TableName: process.env.API_PORTAL_SUBMISSIONSTABLE_NAME,
};
const calculateStatistics = async () => {
try {
const data = await db.query(params).promise();
console.log(data);
} catch (err) {
console.log(err);
}
};
const resolvers = {
Query: {
getStatistics: () => {
return calculateStatistics();
},
},
};
exports.handler = async (event) => {
// TODO implement
const typeHandler = resolvers[event.typeName];
if (typeHandler) {
const resolver = typeHandler[event.fieldName];
if (resolver) {
var result = await resolver(event);
return result;
}
}
}; // };
I then tried to capture the whole event and logged it to the console as can be seen in the calculateStatistics function, which now showed me a bit more explicit error as follows.
{ UnknownEndpoint: Inaccessible host: `dynamodb.us-east-1-fake.amazonaws.com'. This service may not be available in the `us-east-1-fake' region.
at Request.ENOTFOUND_ERROR (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/event_listeners.js:501:46)
at Request.callListeners (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/request.js:688:14)
at ClientRequest.error (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/event_listeners.js:339:22)
at ClientRequest.<anonymous> (/Users/apple/Documents/work/web/portal/amplify/backend/function/calcStatistics/src/node_modules/aws-sdk/lib/http/node.js:96:19)
at ClientRequest.emit (events.js:198:13)
at ClientRequest.EventEmitter.emit (domain.js:448:20)
at TLSSocket.socketErrorListener (_http_client.js:401:9)
at TLSSocket.emit (events.js:198:13)
message:
'Inaccessible host: `dynamodb.us-east-1-fake.amazonaws.com\'. This service may not be available in the `us-east-1-fake\' region.',
code: 'UnknownEndpoint',
region: 'us-east-1-fake',
hostname: 'dynamodb.us-east-1-fake.amazonaws.com',
retryable: true,
originalError:
{ Error: getaddrinfo ENOTFOUND dynamodb.us-east-1-fake.amazonaws.com dynamodb.us-east-1-fake.amazonaws.com:443
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
message:
'getaddrinfo ENOTFOUND dynamodb.us-east-1-fake.amazonaws.com dynamodb.us-east-1-fake.amazonaws.com:443',
errno: 'ENOTFOUND',
code: 'NetworkingError',
syscall: 'getaddrinfo',
hostname: 'dynamodb.us-east-1-fake.amazonaws.com',
host: 'dynamodb.us-east-1-fake.amazonaws.com',
port: 443,
region: 'us-east-1-fake',
retryable: true,
time: 2020-08-12T10:18:08.321Z },
time: 2020-08-12T10:18:08.321Z }
Result:
null
Finished execution.
I then did more research and came across this thread about inaccessible-dynamodb-host-when-running-amplify-mock which I followed and tried implementing to but to no avail. Any help on this would be very much appreciated.
PS: It is worth mentioning that I was able to successfully query for this data through the Appsync console, which led me to strongly believe the problem lies in the function itself.
After doing more research and asking around, I finally made sense of the answer that was provided to me on github that
When running mock on a function which has access to a dynamodb
table generated by API. It will populate the env with fake values. If
you would like to mock your lambda function against your deployed
dynamodb table you can edit the values in the sdk client so it can
make the call accurately.
In summary, if you are running things locally, then you wouldn't have access to your backend variables which you might try mocking. I hope this helps someone. Thanks!
redisClient.get('abc', function(err, abcValue){
console.log(abcValue);
abcValue = abcValue + 'id';
redisClient.set('abc', abcValue, function(err){
console.log('abc updated');
});
});
nested updation over network, prints 'abc updated', but actual value does not update in redis database.
Note:- the above code works on localhost, but update not showing on heroku-redistogo.
Edit:- I'm running code on localhost, with redis connected to Redistogo. Using the following code:-
Setting up of express session:-
app.use(express.session({
store: new RedisStore({
host: 'birdeye.redistogo.com',
port: 1384,
db: 'redistogo',
pass: '052940128c2f2452f73378588dd5fb129'
}),
secret: '1234567890QWERTY',
}));
I am also creating another redisClient using the following code:-
var redisClient = require('redis').createClient( 1384, 'birdeye.redistogo.com', {detect_buffers: true});
redisClient.auth('052940128c2f2452f73378588dd5fb129', function() {
console.log('Redis client connected');
});
Do you see abc updated inside the console when running this code on Heroku ? It seems to be a misconfiguration of Redis client.
I have a little problem with Express and mongoose using Node.js . I pasted the code in pastebin, for a better visibility.
Here is the app.js: http://pastebin.com/FRAFzvjR
Here is the routes/index.js: http://pastebin.com/gDgBXSy6
Since the db.js isn't big, I post it here:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
module.exports = function () {
mongoose.connect('mongodb://localhost/test',
function(err) {
if (err) { throw err; }
}
);
};
var User = new Schema({
username: {type: String, index: { unique: true }},
mdp: String
});
module.exports = mongoose.model('User', User);
As you can see, I used the console.log to debug my app, and I found that, in routes/index.js, only the a appeared. That's weird, it's as if the script stopped (or continue without any response) when
userModel.findOne({username: req.body.username}, function(err, data)
is tried.
Any idea?
You never connect to your database. Your connect method is within the db.export, but that is never called as a function from your app.
Also, you are overwriting your module.exports - if you want multiple functions/classes to be exported, you must add them as different properties of the module.export object. ie.:
module.export.truthy = function() { return true; }
module.export.falsy = function() { return false; }
When you then require that module, you must call the function (trueFalse.truthy();) in order to get the value. Since you never execute the function to connect to your database, you are not recieveing any data.
A couple of things real quick.
Make sure you're on the latest mongoose (2.5.3). Update your package.json and run npm update.
Try doing a console.log(augments) before your if (err). It's possible that an error is happening.
Are you sure you're really connecting to the database? Try explicitly connecting at the top of your file (just for testing) mongoose.connect('mongodb://localhost/my_database');
I'll update if I get any other ideas.