Jade - how to find agent Id and controller Id from agent name - agents-jade

I am currently working on a task which includes actions on jade agent like agent suspend , agent kill etc . Where i get jade agent name from web services . How will i get agent id or agent object from agent name?
public class DPM_MainAgent_WebService_Worker extends Agent {
AMSAgentDescription[] agents = null;
protected void setup()
{
AID aid = new AID("FirstAgent",true);
System.out.println("aid::::::::"+aid);
}
}
FirstName is my agent local name which i am able to get from webservices. I am able to get AID object. But my need is to get agent object. How can i achieve this?
Thanks

There are several questions here :
"How will i get agent id or agent object from agent name ?"
Assuming that the agent you are referring to is on your platform, you can recreate the agent ID (AID) from the (local)name of your agent buy doing this :
new AID("YourAgentName", AID.ISLOCALNAME)
Indeed, and Agent identifier (AID) = localName + ID of the platform
"my need is to get agent object. How can i achieve this?"
The ref to an agent "object" is easily obtained when you create it. You can thus store them somewhere (like a Map < AgentName,AgentRef >).
But generally speaking, it is not recommanded to manipulate agents references as they are thread and may migrate. In most cases its better to ask them to do what you want through messages. Otherwise they are only objects, not agents ;)

Related

How to push Salesforce Order to an external REST API?

I have experience in Salesforce administration, but not in Salesforce development.
My task is to push a Order in Salesforce to an external REST API, if the order is in the custom status "Processing" and the Order Start Date (EffectiveDate) is in 10 days.
The order will be than processed in the down-stream system.
If the order was successfully pushed to the REST API the status should be changed to "Activated".
Can anybody give me some example code to get started?
There's very cool guide for picking right mechanism, I've been studying from this PDF for one of SF certifications: https://developer.salesforce.com/docs/atlas.en-us.integration_patterns_and_practices.meta/integration_patterns_and_practices/integ_pat_intro_overview.htm
A lot depends on whether the endpoint is accessible from Salesforce (if it isn't - you might have to pull data instead of pushing), what authentication it needs.
For push out of Salesforce you could use
Outbound Message - it'd be an XML document sent when (time-based in your case?) workflow fires, not REST but it's just clicks, no code. The downside is that it's just 1 object in message. So you can send Order header but no line items.
External Service would be code-free and you could build a flow with it.
You could always push data with Apex code (something like this). We'd split the solution into 2 bits.
The part that gets actual work done: At high level you'd write function that takes list of Order ids as parameter, queries them, calls req.setBody(JSON.serialize([SELECT Id, OrderNumber FROM Order WHERE Id IN :ids]));... If the API needs some special authentication - you'd look into "Named Credentials". Hard to say what you'll need without knowing more about your target.
And the part that would call this Apex when the time comes. Could be more code (a nightly scheduled job that makes these callouts 1 minute after midnight?) https://salesforce.stackexchange.com/questions/226403/how-to-schedule-an-apex-batch-with-callout
Could be a flow / process builder (again, you probably want time-based flows) that calls this piece of Apex. The "worker" code would have to "implement interface" (a fancy way of saying that the code promises there will be function "suchAndSuchName" that takes "suchAndSuch" parameters). Check Process.Plugin out.
For pulling data... well, target application could login to SF (SOAP, REST) and query the table of orders once a day. Lots of integration tools have Salesforce plugins, do you already use Azure Data Factory? Informatica? BizTalk? Mulesoft?
There's also something called "long polling" where client app subscribes to notifications and SF pushes info to them. You might have heard about CometD? In SF-speak read up about Platform Events, Streaming API, Change Data Capture (although that last one fires on change and sends only the changed fields, not great for pushing a complete order + line items). You can send platform events from flows too.
So... don't dive straight to coding the solution. Plan a bit, the maintenance will be easier. This is untested, written in Notepad, I don't have org with orders handy... But in theory you should be able to schedule it to run at 1 AM for example. Or from dev console you can trigger it with Database.executeBatch(new OrderSyncBatch(), 1);
public class OrderSyncBatch implements Database.Batchable, Database.AllowsCallouts {
public Database.QueryLocator start(Database.BatchableContext bc) {
Date cutoff = System.today().addDays(10);
return Database.getQueryLocator([SELECT Id, Name, Account.Name, GrandTotalAmount, OrderNumber, OrderReferenceNumber,
(SELECT Id, UnitPrice, Quantity, OrderId FROM OrderItems)
FROM Order
WHERE Status = 'Processing' AND EffectiveDate = :cutoff]);
}
public void execute(Database.BatchableContext bc, List<sObject> scope) {
Http h = new Http();
List<Order> toUpdate = new List<Order>();
// Assuming you want 1 order at a time, not a list of orders?
for (Order o : (List<Order>)scope) {
HttpRequest req = new HttpRequest();
HttpResponse res;
req.setEndpoint('https://example.com'); // your API endpoint here, or maybe something that starts with "callout:" if you'd be using Named Credentials
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serializePretty(o));
res = h.send(req);
if (res.getStatusCode() == 200) {
o.Status = 'Activated';
toUpdate.add(o);
}
else {
// Error handling? Maybe just debug it, maybe make a Task for the user or look into
// Database.RaisesPlatformEvents
System.debug(res);
}
}
update toUpdate;
}
public void finish(Database.BatchableContext bc) {}
public void execute(SchedulableContext sc){
Database.executeBatch(new OrderSyncBatch(), Limits.getLimitCallouts()); // there's limit of 10 callouts per single transaction
// and by default batches process 200 records at a time so we want smaller chunks
// https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_limits.htm
// You might want to tweak the parameter even down to 1 order at a time if processing takes a while at the other end.
}
}

s4sdk openSAP develop extension Course - Address not created - no put operation in mock server log

I have created mock server and it shows GET operation selecting all partners and will get a partner by id.
If I click on the Add address button there is no put or post operation in the log file.
Mock server log:
Request: GET
/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner='1003764')?$select=BusinessPartner,CreationDate,FirstName,IsFemale,IsMale,LastName,to_BusinessPartnerAddress/AddressID,to_BusinessPartnerAddress/BusinessPartner,to_BusinessPartnerAddress/CityName,to_BusinessPartnerAddress/Country,to_BusinessPartnerAddress/HouseNumber,to_BusinessPartnerAddress/PostalCode,to_BusinessPartnerAddress/StreetName&$expand=to_BusinessPartnerAddress&$format=json
Reading business partner 1003764
Log from application
12:51:35.357 [http-bio-8080-exec-10] ERROR
com.sap.cloud.sdk.odatav2.connectivity.ODataQuery - Successfully
connected to destination service.
Am I missing a setting?
You can implement an add functionality for a Business Partner Address in the following way:
BusinessPartnerAddress addressToCreate = BusinessPartnerAddress.builder()
.businessPartner(businessPartnerId)
.streetName("someStreet")
.build();
new DefaultBusinessPartnerService()
.createBusinessPartnerAddress(addressToCreate)
.execute();

SoftLayer API: - How to get the ID of a bare metal server on create

I'm using 'SoftLayer_Hardware', 'createObject' to deploy new servers, however this call returns no id, as on the example on http://sldn.softlayer.com/reference/services/SoftLayer_Hardware/createObject
So if I have no id how can I query info for that server? I noticed there's a globalIdentifier variable but no mention at all on what it is and how to use it
you can use the goblal identifier instead the ID in your request
e.g.
Get https://api.softlayer.com/rest/v3.1/SoftLayer_Hardware/$GloblalIdentifier/getObject
Note: replace the $GloblalIdentifier
The reason why the id is not displayed is because the server was not created yet, your order has to be approved and when the provisioning is ended the id will show up, meanwhile you can use the global identifier when the provisioning ends you will be able to see the id
regards
Here SoftLayer_Hardware::createObject says:
To determine when the server is available you can poll the server via
SoftLayer_Hardware::getObject,
checking the provisionDate property. When provisionDate is not null,
the server will be ready. Be sure to use the globalIdentifier as your
initialization parameter.
Please see this example:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Hardware/[globalIdentifier_value]/getObject
Method: GET
Also, you can get Bare Metal information using SoftLayer_Account::getHardware with some filters:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getHardware?objectFilter={"hardware":{"hostname":{"operation": "myhostname"}, "domain":{"operation": "mydomain"}}}&objectMask=mask[id,fullyQualifiedDomainName,provisionDate]
Method: GET
Note: You can add some masks in order to get more information than by default, i.e. In the previous request you can see the provisionDate(When provisionDate is not null, the server will be ready).
List Bare metal servers filtering by username who created them:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getHardware?objectFilter={ "hardware": { "billingItem": { "orderItem": { "order": { "userRecord": { "username": { "operation": "myusername" } } } } } } }&objectMask=mask[id,fullyQualifiedDomainName,billingItem.orderItem.order.userRecord.username,provisionDate]
Method: GET
Also you can review:
Softlayer API to get virtual guest owner
thank you for your answers. Unfortunately this is a chicken/egg problem. Once the API call is sent, I get an GloblalIdentifier but not an id.
If I ask for this GloblalIdentifier I get a response with id as null
If I get the listing of the hardware servers, I see the new machine is there, has an id, but the GloblalIdentifier is None.
Makes no sense.

Multitenant/Shared Application system, how to maintain multiple tentant-specific identifiers?

I have a multi-tenant system where each tenant shares the same instance of the codebase, but has their own databases.
I'm using RavenDB for persistence, with a standard c# facade/BLL backend wrapped with Asp.net WebAPI, and I'm finding that at every lower level operation (deep within my business logic classes) that touch the datbase, I need to pass in an identifier so that my RavenDb client session knows which database to operate against.
When the user authenticates, I resolve the appropriate database identifer, store it in the session manager. Every call against the Web API layer passes in a session ID which resolves the database ID in the backend, which is then used to pass into every single facade/BLL call.
All my dependencies are handled via an IoC container at the WebAPI level, but i can't pass in the database ID at this phase because it can be different for every user that is logged in.
this, of course is getting tedious.
can someone give me some guidance as to what I can do to alleviate this? Maybe perhaps some sort of policy injection/AOP solution?
a rough sample of my backend code looks like..
public class WidgetService()
{
private WidgetBLL _widgetBLL;
private ISessionManager _sessionManager;
public WidgetService(WidgetBLL _widgetBLL, ISessionManager sessionManager)
{
_widgetBLL = widgetBLL;
_sessionManager = sessionManager
}
public Widget getWidget(string sessionId, string widgetId)
{
string DbId = sessionManager.ResolveDbId(sessionId)
return _widgetBLL.GetWidget(string dbId, string widgetId);
}
}
public class WidgetManager()
{
public GetWidget(string dbId, string widgetId)
{
using (IDocumentSession session = documentStore.OpenSession(dbId)
{
var widget = session.load<Widget>(widgetid);
}
return widget;
}
}
the DBID is the identifier for that particular tenant that this particular user is a member of.
You need to change how you are using the session.
Instead of opening and closing the session yourself, do that in the IoC code.
Then you pass a session that is already opened for the right db.

data realted access in authenciation

I am build a web application,and there are some operations is protected for identified people.
I use the sping security for access control,however I have no idea how to control them when deep to the data level.
For exmaple,there are two operation list and edit operation.
Both the administrator of the company and the administrator of one department can access these operations,but the data they can 'list' or 'edit' are not the same.
administrator of the company can get access to all the data of the company while administrator of one department can only get access to the data of his/her department.
So I wonder what is the best practice to implement these requirements?
Most easy method - use PostFilter annotation on service layer.
#Transactional(readonly=true)
#PostFilter("hasPermission(filterObject, 'edit')")
List<DepartamentData> getDepartamenData();
#Transactional
#PreAuthorize("hasPermission(#data, 'edit')")
List<DepartamentData> editDepartamenData(DepartamentData data);
Or another example:
#Transactional(readonly=true)
#PostFilter(
" hasRole('company_admin')" +
"|| (hasRole('departament_admin') && filterObject.departament.equals(principal.departament))")
List<DepartamentData> getDepartamenData();