Guidewire- unable to save details to entity - guidewire

i am trying to save some details in policy center. i am getting those details from billing center and immediately trying to save it but it is giving me exception.
i have called "issuePolicyPeriod" function of billingAPI and returned some values and i need to save this in Policy center.
Exception:
Exception came while saving commision detais: java.lang.RuntimeException: com.guidewire.pl.system.exception.TransactionException: commitBundle must not be called in a transaction.
Code
/**
* Issue a policy period in Billing Center
* #param period: the policy period
* #param transactionID: the unique transaction id to make this call idempotent
*/
override function createPolicyPeriod(period: PolicyPeriod, transactionID : String) : String {
var issuePolicyInfo = new IssuePolicyInfo()
issuePolicyInfo.sync(period)
PCLoggerCategory.BILLING_SYSTEM_PLUGIN.info("Sending policy ${period} to Billing System")
var commissionList = callUpdate(\ b -> b.issuePolicyPeriod(issuePolicyInfo, transactionID))
gw.transaction.Transaction.runWithNewBundle(\ bundle -> {
var commission = new CommissionDetails()
bundle.add(commission)
commission.Commission_SI = new BigDecimal( commissionList.get(1))
commission.CommissionGST_SI = new BigDecimal(commissionList.get(2))
commission.CommissionRate_SI = commissionList.get(3).toString()
})
return commissionList.get(0)
}
I am calling issuePolicyPeriod() function from PC using BillingAPI and returning commission details from BC and trying to save it in PC entity immediately.
Hi,
thank you for your answer. I tried the above code but it is not saving to entity and nor giving any exception. I have a doubt here will current bundle still available? because here we are calling billing center and don't know when BC responds.
in web service calls will guidewire hold the current bundle until response comes back?
When guidewire commits the current bundle in web service calls?

Try to use the current transaction instead of create new.
var commissionList = callUpdate(\ b -> b.issuePolicyPeriod(issuePolicyInfo, transactionID))
var bundle = gw.transaction.Transaction.Current
var commission = new CommissionDetails(bundle)
commission.Commission_SI = new BigDecimal( commissionList.get(1))
commission.CommissionGST_SI = new BigDecimal(commissionList.get(2))
commission.CommissionRate_SI = commissionList.get(3).toString()
return commissionList.get(0)
When you use runWithNewBundle, after block execution ends bundle.commit() it's called

I had a similar error with a bundle (java.lang.RuntimeException: com.guidewire.pl.system.exception.TransactionException: commitBundle must not be called in a transaction)
and I could be solved with this steps
quit or comment this: gw.transaction.Transaction.runWithNewBundle(\ bundle -> {})
The problem was that I had an existing bundle, so I only needed to call it with getCurrent()
var bundle = gw.transaction.Transaction.getCurrent()

Related

content of operation_ParentId in application insights using W3C

I'm currently using an .NET 6.0 isolated function with an HTTP trigger.
Because the activity is not being filled, I've added a middleware that creates the activity based on the W3C traceparent header.
My expectation based on MS docs is that when using Application Insights, the operation_ParentId would relate directly to the ParentSpanId of an Activity where logging is done.
Yet that is not what I'm seeing. What I'm seeing is following
Application A sends a request using traceparent = 00-3abe9f15e940badc5f1521e6eb1eb411-bfd30439c918c783-00
In middleware of application B, an activity is started and a message is logged. I can also validate that the ParentId of the activity is equal to 00-3abe9f15e940badc5f1521e6eb1eb411-bfd30439c918c783-00. The ParentSpanId is equal to bfd30439c918c783
using var requestActivity = new Activity(context.FunctionDefinition.Name);
requestActivity.SetParentId(traceParent);
requestActivity.Start();
_logger.LogInformation("Invoking '{Name}'", context.FunctionDefinition.Name);
In application insights I see OperationId being equal to the WC3 trace-id 3abe9f15e940badc5f1521e6eb1eb411 as expected. However, the operation_ParentId is a span I've not seen before. It is neither the requestActivity.SpanId nor the requestActivity.ParentSpanId.
What is happening that I do not understand? Does Application Insights not use the active Activity when logging?
my app configuration
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker =>
{
worker.UseMiddleware<TracingMiddleware>();
})
.ConfigureServices(collection =>
{
})
.ConfigureLogging(x=>x.AddApplicationInsights())
.Build();
host.Run();
My middleware function
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
{
using var requestActivity = new Activity(context.FunctionDefinition.Name);
SetParentId(context, requestActivity);
requestActivity.Start();
_logger.LogInformation("Invoking '{Name}'", context.FunctionDefinition.Name);
var t = Activity.Current;
System.Console.WriteLine();
System.Console.WriteLine($"Activity.TraceId: {t.TraceId}");
System.Console.WriteLine($"Activity.ParentId: {t.ParentId}");
System.Console.WriteLine($"Activity.SpanId: {t.SpanId}");
await next(context);
var statusCode = (context.Items != null)
? context.GetHttpResponseData()?.StatusCode
: System.Net.HttpStatusCode.OK;
_logger.LogInformation(
"Executed '{Name}', Result {Result}, Duration = {Duration}ms",
context.FunctionDefinition.Name,
statusCode,
(DateTime.UtcNow - requestActivity.StartTimeUtc).TotalMilliseconds);
requestActivity.Stop();
}
As per the MS-Doc the Operation ID is equal to TraceId. And the Operation_parent Id has the combination of both Trace-ID with Parent-ID. The Format has .
The operation_ParentId field is in the format
<trace-id>.<parent-id>, where both trace-id and parent-id are
taken from the trace header that was passed in the request.
I have noticed that It was not actually same. I have tired with many possible ways. I end up with The operation-ID is not equal to the Trace-ID and the Operation-parent-ID is not equal to < Trace-ID>.< Parent-ID>.
In my middle ware i have added the current context like below
ILogger logger = context.GetLogger<MyCustomMiddleware>();
//logger.LogInformation("From function: {message}", message);
using var requestActivity = new Activity(context.FunctionDefinition.Name);
//t.SetParentId(context, requestActivity);
requestActivity.Start();
logger.LogInformation("Invoking '{Name}'", context.FunctionDefinition.Name);
//requestActivity.SetParentId(Convert.ToString(requestActivity.RootId));
requestActivity.SetParentId(requestActivity.TraceId,requestActivity.SpanId,ActivityTraceFlags.None);
var t = Activity.Current;
//Activity.SetParentId(context, requestActivity,);
//t.SetParentId(context, requestActivity)
logger.LogInformation($"Activity.TraceId: {t.TraceId}");
logger.LogInformation($"Activity.ParentId: {t.ParentId}");
logger.LogInformation($"Activity.SpanId: {t.SpanId}");
logger.LogInformation($"Activity.Id: {t.Id}");
logger.LogInformation($"Activity.ParentSpanId: {t.ParentSpanId}");
logger.LogInformation($"Activity.RootId: {t.RootId}");
logger.LogInformation($"Activity.Parent: {t.Parent}");
Result I got.
Refer here for one of my workarounds with more details.

Fail to join the meeting (ZOOM-SDK)

I’m new to Zoom. what I’m trying to do is to integrate zoom meeting into my ReactJS app.
first of all, I tried to use the zoom sample web app to check how it works.
so I cloned this project from
GitHub - zoom/sample-app-web: Zoom Meeting SDK for Web Sample App
following the readme instruction
I created a new app in the marketplace.zoom to get needed credentials API__key API_secrect
also, I used this function to create a new signature
function generateSignature(apiKey, apiSecret, meetingNumber, role) {
// Prevent time sync issue between client signature generation and Zoom
const timestamp = new Date().getTime() - 30000
const msg = Buffer.from(apiKey + meetingNumber + timestamp + role).toString('base64')
const hash = crypto.createHmac('sha256', apiSecret).update(msg).digest('base64')
const signature = Buffer.from(apiKey, meetingNumber, timestamp, role, hash).toString('base64')
return signature
}
but when I tried to join a meeting
I got this error
{
"type": "JOIN_MEETING_FAILED",
"reason": "Fail to join the meeting.",
"errorCode": 200
}
Can you please help me out?

Amazon Pinpoint Endpoints in putEvents-Method of the JavaScript SDK aren't working

I've built a AWS Pinpoint integration into my app using API Gateway and Events are properly coming into Pinpoint. However with every new request a new Endpoint is created although I supply the "address"-field.
I went through all the docs provided by AWS:
https://docs.aws.amazon.com/pinpoint/latest/apireference/apps-application-id-events.html
https://docs.aws.amazon.com/pinpoint/latest/developerguide/integrate-events.html
Primarily used this class doc which seems to have some missing info:
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Pinpoint.html
async function putEvent(clientRequest){
/* create the putEvents parameters */
var param = {
ApplicationId: PINPOINT_APP_ID,
EventsRequest: {
BatchItem: { }
}
};
/* create the event parameter */
var eventParam = {
Endpoint: {
Address: clientRequest.deviceId,
ChannelType: 'CUSTOM',
Demographic: {
AppVersion: clientRequest.app.version,
Locale: clientRequest.system.locale,
Make: clientRequest.device.manufacturer,
Model: clientRequest.device.model,
ModelVersion: clientRequest.device.version,
Platform: clientRequest.platform.name,
PlatformVersion: clientRequest.platform.version
}
}
};
/* add the location if its was provided */
if(clientRequest.hasOwnProperty('location')){
/* add the latitude and longitude values */
eventParam.Endpoint['Location'] = {
Latitude: clientRequest.location.latitude,
Longitude: clientRequest.location.longitude
}
/* check if a city and postal code was supplied
alongside the country value */
if(clientRequest.location.hasOwnProperty('cityName') == true
&& clientRequest.location.hasOwnProperty('countryCode') == true
&& clientRequest.location.hasOwnProperty('postalCode') == true){
/* attach to the location param */
eventParam.Endpoint.Location['Country'] = clientRequest.location.countryCode;
eventParam.Endpoint.Location['City'] = clientRequest.location.postalCode;
eventParam.Endpoint.Location['PostalCode'] = clientRequest.location.cityName;
}
}
/* check if the userId was supplied */
if(clientRequest.hasOwnProperty('userId')){
/* attach the hashed and salted user id */
eventParam.Endpoint['User'] = {UserId: getSHA512(clientRequest.userId+USERID_HASHSALT)};
}
/* attach the event values */
eventParam['Events'] = [{
EventType: clientRequest.event.name,
Timestamp: (new Date()).toISOString()
}];
/* create a unique request id */
var requestId = (new Date().getTime()) + Math.floor(Math.random() * 10);
param.EventsRequest.BatchItem[requestId] = eventParam;
/* flush an event to Pinpoint */
await Pinpoint.putEvents(param).promise();
}
After every request I do have a new Pinpoint Endpoint defined, although I provide a unique Address-value for each Endpoint.
a) What do I need to do have the Endpoints unique?
b) How can I report Sign-ins, Sign-out and the other Events?
^ Could not find them in the documentation
Agreed the Pinpoint docs / class document is incomplete leaving out desired information. From my experiencing testing & using the API this is what I have found which hopefully can be of use.
a) What do I need to do have the Endpoints unique?
Pinpoint.putEvents not only creates a new event for an endpoint but it also creates or updates endpoint data
The fact that Pinpoint.putEvents can create or update an endpoint is causing the error you've encountered where a new endpoint is created after every event request.
This is because you are accidentally creating a new endpoint equal to the random requestId for each event that you send when setting the keys of BatchItem. The object keys of BatchItem are actually supposed to be the endpointId the event is supposed to be associated with opposed to the requestId for the event (This is not mentioned at all in the docs!)
To keep endpoints unique you first need to know what the unique endpoint is for the user in addition to the address and unique UserId (This seems to be missing from pinpoint docs. I realized it when trying to update or delete an endpoint which you cannot do by address as you need the endpointId). From your example I would choose something related to the userId concatenated with the channel type if you plan on having multiple channels for a single user as pinpoint does allow messages to be sent through email, sms and recorded voice calls (you've listed "CUSTOM" but I'd try to use one of the enum's that is actually associated with how the message would be delivered. I believe this allows this endpoint to work better with different types of pinpoint campaigns and journeys to send messages to your users)
// Original code adding eventParam to param.EventsRequest.BatchItem incorrectly by random requestId
var requestId = (new Date().getTime()) + Math.floor(Math.random() * 10);
param.EventsRequest.BatchItem[requestId] = eventParam;
// correct code associating eventParam with a unique endpointId
var endpointId = eventParam.Endpoint.User.UserId+'CUSTOM'
param.EventsRequest.BatchItem[endpointId] = eventParam;
Additionally keep in mind that all of the information you have added to eventParam.endpoint will update / overwrite whatever is currently stored for those endpointId attributes when calling Pinpoint.putEvents so watch out for that
b) How can I report Sign-ins, Sign-out and the other Events?
I believe to report sign-ins / sign-outs that are visualized in the pinpoint dashboard follow the event naming convention in the Pinpoint app events documentation
so for sign-ins the event name is _userauth.sign_in
I don't think sign outs are displayed automatically on the Anlaytics -> Usage dashboard but you can use any consistent event name for sign outs and then use pinpoint filters to see those events through time.

How to use Pinpoint send messages to specific devices using the Java AWS SDK for Pinpoint

I have been able to get my mobile Android app to receive messages generated from the Pinpoint Campaign console (https://console.aws.amazon.com/pinpoint/home) to a specific device by targeting the segment to a custom attribute that only that device has.
Pinpoint Campaign config
Mobile push channel
Standard campaign
Segment defined using custom attributes, holdout 0%
Silent notification
Custom JSON
Launch immediate
Now I would like to implement this feature in my Java app using the SDK APIs and target the device's Pinpoint endpoint.
GetEndpointRequest getEndpointRequest = new GetEndpointRequest()
.withApplicationId(appId)
.withEndpointId(endpointId);
GetEndpointResult endpointResult = getAmazonPinpointClient().getEndpoint(getEndpointRequest);
DirectMessageConfiguration directMessageConfiguration =
new DirectMessageConfiguration().withGCMMessage(new GCMMessage().withBody(body).withSilentPush(true).withAction(Action.OPEN_APP));
AddressConfiguration addressConfiguration = new AddressConfiguration().withChannelType(ChannelType.GCM);
MessageRequest messageRequest = new MessageRequest().withMessageConfiguration(directMessageConfiguration)
.addAddressesEntry(endpointResponse.getAddress(), addressConfiguration);
SendMessagesRequest sendMessagesRequest = new SendMessagesRequest()
.withApplicationId(appId)
.withMessageRequest(messageRequest);
The "body" is the same JSON I put in the Pinpoint Campaign console. When I run this, I get back a DeliveryStatus of SUCCESSFUL but the device never receives the message.
{ApplicationId: MY_APP_ID,Result: {clrVUcv-AwA:APA91bHGXkxpDJiw5kOMROA2XTJXuKreMklq9jemHO_KGYTIw6w84Fw9zLv9waMgLgha61IR-kZxgmrnFu-OGp8l6WFgp4Wolh4oOvZwMobGYNgzivv3bGIK83t-e4hiLx1TTaEIeRdQ={DeliveryStatus: SUCCESSFUL,StatusCode: 200,StatusMessage: {"multicast_id":4803589342422496921,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1515105369948916%c551fa42f9fd7ecd"}]},}}}
I have also tried this via the AWS CLI:
aws pinpoint send-messages --application-id MY_APP_ID --message-request "{\"Addresses\":{\"clrVUcv-AwA:APA91bHGXkxpDJiw5kOMROA2XTJXuKreMklq9jemHO_KGYTIw6w84Fw9zLv9waMgLgha61IR-kZxgmrnFu-OGp8l6WFgp4Wolh4oOvZwMobGYNgzivv3bGIK83t-e4hiLx1TTaEIeRdQ\":{\"ChannelType\":\"GCM\"}},\"MessageConfiguration\":{\"GCMMessage\":{\"Body\":\"{\\\"message\\\":\\\"stuff\\\"}\",\"SilentPush\":true}}}"
with a similar result (get 200 status code and DeliveryStatus of SUCCESSFUL but the app never receives). I tried using the "Direct" message in the AWS Pinpoint console but they do not seem to support the same format (forces Action and Title/Message instead of silent push message with custom JSON).
Am I getting the endpoint incorrectly? How do I translate the above campaign into a message? I see there is a sendUserMessages() API call as well but that doesn't seem to be right one (I couldn't find where to specify the specific user endpoint)?
The client receives the campaign via the registered Service:
public class PushListenerService extends GcmListenerService {
#Override
public void onMessageReceived(final String from, final Bundle data) {
AWSMobileClient.initializeMobileClientIfNecessary(this.getApplicationContext());
final NotificationClient notificationClient = AWSMobileClient.defaultMobileClient()
.getPinpointManager().getNotificationClient();
NotificationClient.CampaignPushResult pushResult =
notificationClient.handleGCMCampaignPush(from, data, this.getClass());
Log.e(LOG_TAG, " onMessageReceived - got messages" + data);
Do GCM direct messages get sent through the same campaign method or do I have to register a different service to process these?
Found the solution based on the AWS CLI command I was able to run. Should have been using the "Data" element and not the "Body" and need to enable "SilentPush".
EndpointResponse endpointResponse = getPinpointEndpointResponse(appId, pinpointEndpointId);
Map<String, String> data = new HashMap<>();
// construct data here, currently only supports Map<String, String>
// why not HashMap<String, Object> so it can support full JSON????
DirectMessageConfiguration directMessageConfiguration =
new DirectMessageConfiguration().withGCMMessage(new GCMMessage().withData(data).withSilentPush(true));
AddressConfiguration addressConfiguration = new AddressConfiguration().withChannelType(ChannelType.GCM);
MessageRequest messageRequest = new MessageRequest().withMessageConfiguration(directMessageConfiguration)
.addAddressesEntry(endpointResponse.getAddress(), addressConfiguration);
SendMessagesRequest sendMessagesRequest = new SendMessagesRequest()
.withApplicationId(appId)
.withMessageRequest(messageRequest);

Same Azure topic is processed multiple times

We have a job hosted in an azure website, the job reads entries from a topic subscription. Everything works fine when we only have one instance to host the website. Once we scale out to more than one instance we observe the message is processed as many times as instances we have. Each instance points to the same subscription. From what we read, once the item is read, it won't be available for any other process. The duplicated processing is happening inside the same instance, meaning that if we have two instances, the item is processed twice in one of the instances, it is not splitted.
What can be possible be wrong in the way we are doing things?
This is how we proceed to configure the connection to the queue, if the subscription does not exists, it is created:
var serviceBusConfig = new ServiceBusConfiguration
{
ConnectionString = transactionsBusConnectionString
};
config.UseServiceBus(serviceBusConfig);
var allRule1 = new RuleDescription
{
Name = "All",
Filter = new TrueFilter()
};
SetupSubscription(transactionsBusConnectionString,"topic1", "subscription1", allRule1);
private static void SetupSubscription(string busConnectionString, string topicNameKey, string subscriptionNameKey, RuleDescription newRule)
{
var namespaceManager =
NamespaceManager.CreateFromConnectionString(busConnectionString);
var topicName = ConfigurationManager.AppSettings[topicNameKey];
var subscriptionName = ConfigurationManager.AppSettings[subscriptionNameKey];
if (!namespaceManager.SubscriptionExists(topicName, subscriptionName))
{
namespaceManager.CreateSubscription(topicName, subscriptionName);
}
var subscriptionClient = SubscriptionClient.CreateFromConnectionString(busConnectionString, topicName, subscriptionName);
var rules = namespaceManager.GetRules(topicName, subscriptionName);
foreach (var rule in rules)
{
subscriptionClient.RemoveRule(rule.Name);
}
subscriptionClient.AddRule(newRule);
rules = namespaceManager.GetRules(topicName, subscriptionName);
rules.ToString();
}
Example of the code that process the topic item:
public void SendInAppNotification(
[ServiceBusTrigger("%eventsTopicName%", "%SubsInAppNotifications%"), ServiceBusAccount("OutputServiceBus")] Notification message)
{
this.valueCalculator.AddInAppNotification(message);
}
This method is inside a Function static class, I'm using azure web job sdk.
Whenever the azure web site is scaled to more than one instance, all the instances share the same configuration.
It sounds like you're creating a new subscription each time your new instance runs, rather than hooking into an existing one. Topics are designed to allow multiple subscribers to attach in that way as well - usually though each subscriber has a different purpose, so they each see a copy of the message.
I cant verify this from your code snippet but that's my guess - are the config files identical? You should add some trace output to see if your processes are calling CreateSubscription() each time they run.
I think I can access the message id, I'm using azure web job sdk but I think I can find a way to get it. Let me check it and will let you know.

Resources