How can I fix update_mask.paths error on AnalyticsAdminServiceClient(GA4) Nodejs? - node.js

I tried to update "DataRetentionSettings" using Google Analytics Admin Client(GA4) in Nodejs, but I got the following error.
Error: 3 INVALID_ARGUMENT: One or more values in the field 'update_mask.paths_list' was invalid, but all values must be valid.eventDataRetention, resetUserDataOnNewActivity
at Object.callErrorFromStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\call.js:31:26)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client.js:189:52)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:365:141)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:328:181)
at C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\call-stream.js:187:78
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 3,
details: "One or more values in the field 'update_mask.paths_list' was invalid, but all values must be valid.eventDataRetention, resetUserDataOnNewActivity",
metadata: Metadata {
internalRepr: Map(1) { 'grpc-server-stats-bin' => [Array] },
options: {}
},
note: 'Exception occurred in retry method that was not classified as transient'
}
The code is as follows.
const analyticsAdmin = require("#google-analytics/admin");
class Main {
constructor() {
this.analyticsAdminClient = new analyticsAdmin.AnalyticsAdminServiceClient({
keyFilename: "./mykeyfile.json",
});
}
async updateDataRetentionSettings() {
const name = "properties/*********/dataRetentionSettings";
const request = {
dataRetentionSettings: {
name: name,
eventDataRetention: "FOURTEEN_MONTHS",
resetUserDataOnNewActivity: true,
},
updateMask: {
paths: ["eventDataRetention", "resetUserDataOnNewActivity"],
},
};
let retention = {};
try {
retention = await this.analyticsAdminClient.updateDataRetentionSettings(request);
} catch (e) {
console.log(e);
process.exit(1);
}
return retention[0];
}
}
const client = new Main();
client.updateDataRetentionSettings();
I also added "name" to the paths property of updateMask and the result was the same.
Here is the document I referred to.
AnalyticsAdminServiceClient
And the client version is 4.0.0.
How can I update DataRetentionSettings via API?

To update property in GA 4 then you could try as follows :
const {AnalyticsAdminServiceClient} = require('#google-analytics/admin').v1alpha; // ---> This dependency should be installed
const credentialFile = '/usr/local/credentialFile.json';
const adminClient = new AnalyticsAdminServiceClient(
{keyFilename: credentialFile} // --> credentialFile will be the path of service account's detail json file in your local machine
);
async function callUpdateProperty() {
// Construct request
const updateMask = {
paths: ["display_name"] // --> Please keep in mind that name should in camel case. like I have added for 'displayName' as 'display_name'
};
const property = {
"name" : "properties/123",
"displayName": "New Display Name"
};
const request = {
property,
updateMask,
};
// Run request
const response = await adminClient.updateProperty(request);

Related

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

JMS Text Message on Oracle AQ from Nodejs

I'm trying to enqueue a jms text message on oracle AQ from nodejs.
const enqueue = async () => {
try {
await oracle.createPool();
const connection = await oracle.getConnection();
const jmsMessageType = "SYS.AQ$_JMS_TEXT_MESSAGE";
const queue = await connection.getQueue(bv.REQUEST_QUEUE_NAME, {payloadType: jmsMessageType});
const theRequest = new queue.payloadTypeClass({
text_length: request.length,
text_vc: request
});
await queue.enqOne(theRequest);
await connection.commit();
} catch(e){
console.error(e);
}
}
enqueue();
I can see that the message is queued in the AQ's table in oracle, but the consumer breaks when trying to dequeue the message:
oracle.jms.AQjmsException: JMS-120: Dequeue failed
at oracle.jms.AQjmsError.throwEx(AQjmsError.java:337)
at oracle.jms.AQjmsConsumer.jdbcDequeueCommon(AQjmsConsumer.java:1995)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1374)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1292)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1270)
at oracle.jms.AQjmsConsumer.receiveNoWait(AQjmsConsumer.java:1068)
...
Caused by: java.lang.NullPointerException
at oracle.jms.AQjmsTextMessage.readTextMessageContainer(AQjmsTextMessage.java:328)
at oracle.jms.AQjmsTextMessage.<init>(AQjmsTextMessage.java:161)
at oracle.jms.AQjmsConsumer.jdbcDequeueCommon(AQjmsConsumer.java:1751)
... 19 more
Any ideas on the correct structure of the JMSTextMessage type?
Basically just had to get the definitions of the types and user UPPER CASE for the property names. Upper case is very important - it just ignores lower case property names.
SYS.AQ$_JMS_TEXT_MESSAGE
SYS.AQ$_JMS_HEADER
SYS.AQ$_JMS_USERPROPARRAY
SYS.AQ$_JMS_USERPROPERTY
Look here if you need more:
https://docs.oracle.com/cd/B10501_01/appdev.920/a96612/t_jms3.htm
const theRequest = new queue.payloadTypeClass(
{
HEADER: {
USERID: "YOUR_USER",
PROPERTIES: [
{
NAME: "JMS_OracleDeliveryMode",
TYPE: 100,
STR_VALUE: "2",
NUM_VALUE: null,
JAVA_TYPE: 27
},
{
NAME: "JMS_OracleTimestamp",
TYPE: 200,
STR_VALUE: null,
NUM_VALUE: new Date().getTime(),
JAVA_TYPE: 24
}
]
},
TEXT_LEN: request.length,
TEXT_VC: request
}
);

Predict AutoML google return INVALID_ARGUMENT on NodeJS

I have a problem with my AutoML code. I want to link it to a web project. I've used the Google tutorial but it doesn't work. I receive this error in my console :
payload : { row:
{ values:
[ [Object], [Object], [Object], [Object], [Object], [Object] ] } }
{ Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
at Object.callErrorFromStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call.js:30:26)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client.js:175:52)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client-interceptors.js:341:141)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client-interceptors.js:304:181)
at Http2CallStream.outputStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:116:74)
at Http2CallStream.maybeOutputStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:155:22)
at Http2CallStream.endCall (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:141:18)
at Http2CallStream.handleTrailers (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:273:14)
at ClientHttp2Stream.emit (events.js:198:13)
at emit (internal/http2/core.js:265:8)
code: 3,
details: 'Request contains an invalid argument.',
metadata:
Metadata {
internalRepr: Map { 'grpc-server-stats-bin' => [Array] },
options: {} } }
Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
My code looks like this
It Comes from this github repo
I've created the JSON credentials to use my ML code to website
On this project, I use Express (i've deleted the code for you)
// ========================================
// Config modules
// ========================================
const clientOptions = {
apiEndpoint: 'eu-automl.googleapis.com'
};
const client = new automl.v1beta1.PredictionServiceClient(clientOptions);
// =======================================
// Function for api route
// =======================================
const projectId = '*****'; // Project ID from GCP
const computeRegion = 'eu'; // eu (like my bucket)
const modelId = '******'; // modelID from my CGP Table ML
const modelFullId = client.modelPath(projectId, computeRegion, modelId);
console.log("modelFullId :", modelFullId)
const sendDataPredict = async (data) => {
let values = [];
for (const val in data) {
values.push({
[typeof val == 'string' ? 'stringValue' : 'numberValue']: val
});
}
const payload = {
row: {
values: values
},
};
I've tried with Postman but i have the same error.
Many thanks for all your help
Try to use this:
const clientOptions = {
apiEndpoint: 'eu-automl.googleapis.com',
port: '443'
};

Mock multiple api call inside one function using Moxios

I am writing a test case for my service class. I want to mock multiple calls inside one function as I am making two API calls from one function. I tried following but it is not working
it('should get store info', async done => {
const store: any = DealersAPIFixture.generateStoreInfo();
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: store
});
const nextRequest = moxios.requests.at(1);
nextRequest.respondWith({
status: 200,
response: DealersAPIFixture.generateLocation()
});
});
const params = {
dealerId: store.dealerId,
storeId: store.storeId,
uid: 'h0pw1p20'
};
return DealerServices.retrieveStoreInfo(params).then((data: IStore) => {
const expectedOutput = DealersFixture.generateStoreInfo(data);
expect(data).toMatchObject(expectedOutput);
});
});
const nextRequest is always undefined
it throw error TypeError: Cannot read property 'respondWith' of undefined
here is my service class
static async retrieveStoreInfo(
queryParam: IStoreQueryString
): Promise<IStore> {
const res = await request(getDealerStoreParams(queryParam));
try {
const locationResponse = await graphQlRequest({
query: locationQuery,
variables: { storeId: res.data.storeId }
});
res.data['inventoryLocationCode'] =
locationResponse.data?.location?.inventoryLocationCode;
} catch (e) {
res.data['inventoryLocationCode'] = 'N/A';
}
return res.data;
}
Late for the party, but I had to resolve this same problem just today.
My (not ideal) solution is to use moxios.stubRequest for each request except for the last one. This solution is based on the fact that moxios.stubRequest pushes requests to moxios.requests, so, you'll be able to analyze all requests after responding to the last call.
The code will look something like this (considering you have 3 requests to do):
moxios.stubRequest("get-dealer-store-params", {
status: 200,
response: {
name: "Audi",
location: "Berlin",
}
});
moxios.stubRequest("graph-ql-request", {
status: 204,
});
moxios.wait(() => {
const lastRequest = moxios.requests.mostRecent();
lastRequest.respondWith({
status: 200,
response: {
isEverythingWentFine: true,
},
});
// Here you can analyze any request you want
// Assert getDealerStoreParams's request
const dealerStoreParamsRequest = moxios.requests.first();
expect(dealerStoreParamsRequest.config.headers.Accept).toBe("application/x-www-form-urlencoded");
// Assert graphQlRequest
const graphQlRequest = moxios.requests.get("POST", "graph-ql-request");
...
// Assert last request
expect(lastRequest.config.url).toBe("status");
});

Need to find the error with connecting subscription with schema stitching

I am using apollo-server-express for graphql back-end. I am going to process only mutations there, but I want to redirect query and subscription on hasura by means of schema stitching with introspection. Queries through apollo-server to hasura are working fine and returning the expected data.
But subscriptions are not working and I am getting this error: " Expected Iterable, but did not find one for field subscription_root.users".
And besides, server hasura is receiving events:
But apollo-server resents the answer from hasura. It is not the first day I suffer with this and I can not understand what the problem is.
In the editor hasura subscriptions work.
Link to full code
If you need any additional info, I will gladly provide it to you.
import {
introspectSchema,
makeExecutableSchema,
makeRemoteExecutableSchema,
mergeSchemas,
transformSchema,
FilterRootFields
} from 'graphql-tools';
import { HttpLink } from 'apollo-link-http';
import nodeFetch from 'node-fetch';
import { resolvers } from './resolvers';
import { hasRoleResolver } from './directives';
import { typeDefs } from './types';
import { WebSocketLink } from 'apollo-link-ws';
import { split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import * as ws from 'ws';
import { OperationTypeNode } from 'graphql';
interface IDefinitionsParams {
operation?: OperationTypeNode,
kind: 'OperationDefinition' | 'FragmentDefinition'
}
const wsurl = 'ws://graphql-engine:8080/v1alpha1/graphql';
const getWsClient = function (wsurl: string) {
const client = new SubscriptionClient(wsurl, {
reconnect: true,
lazy: true
}, ws);
return client;
};
const wsLink = new WebSocketLink(getWsClient(wsurl));
const createRemoteSchema = async () => {
const httpLink = new HttpLink({
uri: 'http://graphql-engine:8080/v1alpha1/graphql',
fetch: (nodeFetch as any)
});
const link = split(
({ query }) => {
const { kind, operation }: IDefinitionsParams = getMainDefinition(query);
console.log('kind = ', kind, 'operation = ', operation);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink,
);
const remoteSchema = await introspectSchema(link);
const remoteExecutableSchema = makeRemoteExecutableSchema({
link,
schema: remoteSchema
});
const renamedSchema = transformSchema(
remoteExecutableSchema,
[
new FilterRootFields((operation, fieldName) => {
return (operation === 'Mutation') ? false : true; // && fieldName === 'password'
})
]
);
return renamedSchema;
};
export const createNewSchema = async () => {
const hasuraExecutableSchema = await createRemoteSchema();
const apolloSchema = makeExecutableSchema({
typeDefs,
resolvers,
directiveResolvers: {
hasRole: hasRoleResolver
}
});
return mergeSchemas({
schemas: [
hasuraExecutableSchema,
apolloSchema
]
});
};
Fixed by installing graphql-tools 4th version. It tutns out the editor did not even notice that I do not have this dependency and simply took the version of node_modules, which was installed by some other package. Problem was with version 3.x. Pull request is where the bug was fixed.
I had the same problem, different cause and solution.
My subscription was working well, until I introduced the 'resolve' key in
my subscription resolver:
Here is the 'Subscription' part of My resolver:
Subscription: {
mySubName: {
resolve: (payload) => {
console.log('In mySubName resolver, payload:',payload)
return payload;
},
subscribe:() => pubSub.asyncIterator(['requestsIncomplete']),
// )
},
The console.log proved the resolve() function was being called with a well structured payload (shaped the same as my Schema definiton - specifically the an object with a key named after the graphQL Subscriber, pointing to an array (array is an iterable):
In mySubName resolver, payload: { mySubName:
[ { id: 41,
...,
},
{...},
{...}
...
...
]
Even though I was returning that same unadulterated object, it caused the error expected Iterable, but did not find one for field "Subscription.mySubName"
When I commented out that resolve function all together, the subscription worked, which is further evidence that my payload was well structured, with the right key pointing to an iterable.
I must be mis-using the resolve field. From https://www.apollographql.com/docs/graphql-subscriptions/subscriptions-to-schema/
When using subscribe field, it's also possible to manipulate the event
payload before running it through the GraphQL execution engine.
Add resolve method near your subscribe and change the payload as you wish
so I am not sure how to properly use that function, specifically don't know what shape object to return from it, but using it as above breaks the subscription in the same manner you describe in your question.
I was already using graphql-tools 4.0.0, I upgraded to 4.0.8 but it made no difference.

Resources