I am using the Microsoft Dynamics CRM, using the Java API generated as per their tutorial and SDK downloads.
I can create, delete, and update entities with no problems.
I am now at the stage where I need to set entities to active or inactive.
I had thought that the right way to do this was roughly
public void doIt(OrganisationServicesStub stub, OptionSetValue stateValue, OptionSetValue statusValue)
{
Guid g = new Guid();
g.setGuid("abc-def-ghijkl");
Entity updateMe = new Entity();
updateMe.setId(g);
updateMe.setLogicalName("ei_teacherdetails");
AttributeCollection updateCollection = new AttributeCollection();
updateCollection.addKeyValuePairOfstringanyType(pair("statecode", stateValue));
updateCollection.addKeyValuePairOfstringanyType(pair("statuscode", statusValue));
updateMe.setAttributes(updateCollection);
update.setEntity(updateMe);
stub.update(update);
}
public static KeyValuePairOfstringanyType pair(String key, Object value)
{
KeyValuePairOfstringanyType attr = new KeyValuePairOfstringanyType();
attr.setKey(key);
attr.setValue(value);
return attr;
}
The above code has been tested and works for updating any attributes except the state/status ones. When I try the above code, however, (i.e. the code that tries to update the state/status), I get the following error (calling with state/status values of 1 and 2 respectively. I got those values by looking at existing Invalid entries in the CRM dumped through the same api, so I am (almost) certain that they are correct.
org.apache.axis2.AxisFault: 2 is not a valid status code for state code ei_teacherdetailsState.Active
I have noticed that in other languages, there is a SetState request, but I don't find a similar one in Java.
If anyone has been down this path before me, I'd greatly appreciate any assistance you could give.
It turns out that the correct answer is as follows, as best I can tell....
private void doIt(OrganizationServiceStub stub, OptionSetValue state, OptionSetValue status)
{
OrganizationRequest request = new OrganizationRequest();
request.setRequestName("SetState");
ParameterCollection collection = new ParameterCollection();
collection.addKeyValuePairOfstringanyType(pair("State", state));
collection.addKeyValuePairOfstringanyType(pair("Status", status));
request.setParameters(collection);
Guid g = new Guid();
g.setGuid("abc0def-ghi");
EntityReference ref = new EntityReference();
ref.setId(g);
ref.setLogicalName("ei_teacherdetails");
collection.addKeyValuePairOfstringanyType(pair("EntityMoniker", ref));
Execute exe = new Execute();
exe.setRequest(request);
stub.execute(exe);
}
Which is pretty obscure, I think. Especially I like that there's a parameter called "EntryMoniker". Anyway, I leave this answer here just in case some other poor soul ends up having to deal with this MS CRM intricacy.
Related
I am just getting started with IBKR API on Java. I am following the API sample code, specifically the options chain example, to figure out how to get options chains for specific stocks.
The example works well for this, but I have one question - how do I know once ALL data has been loaded? There does not seem to be a way to tell. The sample code is able to tell when each individual row has been loaded, but there doesn't seem to be a way to tell when ALL strikes have been successfully loaded.
I thought that using tickSnapshotEnd() would be beneficial, but it doesn't not seem to work as I would expect it to. I would expect it to be called once for every request that completes. For example, if I do a query for a stock like SOFI on the 2022/03/18 expiry, I see that there are 35 strikes but tickSnapshotEnd() is called 40+ times, with some strikes repeated more than once.
Note that I am doing requests for snapshot data, not live/streaming data
reqOptionsMktData is obviously a method in the sample code you are using. Not sure what particular code your using, so this is a general response.
Firstly you are correct, there is no way to tell via the API, this must be done by the client. Of course it will provide the requestID that was used when the request was made. The client needs to remember what each requestID was for and decide how to process that information when it is received in the callbacks.
This can be done via a dictionary or hashtable, where upon receiving data in the callback then check if the chain is complete.
Message delivery from the API often has unexpected results, receiving extra messages is common and is something that needs to be taken into account by the client. Consider the API stateless, and track everything in the client.
Seems you are referring to Regulatory Snapshots, I would encourage you to look at the cost. It could quite quickly add up to the price of streaming live data. Add to that the 1/sec limit will make a chain take a long time to load. I wouldn't even recommend using snapshots with live data, cancelling the request yourself is trivial and much faster.
Something like (this is obviously incomplete C#, just a starting point)
class OptionData
{
public int ReqId { get; }
public double Strike { get; }
public string Expiry { get; }
public double? Bid { get; set; } = null;
public double? Ask { get; set; } = null;
public bool IsComplete()
{
return Bid != null && Ask != null;
}
public OptionData(int reqId, double strike, ....
{ ...
}
...
class MyData()
{
// Create somewhere to store our data, indexed by reqId.
Dictionary<int, OptionData> optChain = new();
public MyData()
{
// We would want to call reqSecDefOptParams to get a list of strikes etc.
// Choose which part of the chain you want, likely you'll want to
// get the current price of the underlying to decide.
int reqId = 1;
...
optChain.Add(++reqId, new OptionData(reqId,strike,expiry));
...
// Request data for each contract
// Note the 50 msg/sec limit https://interactivebrokers.github.io/tws-api/introduction.html#fifty_messages
// Only 1/sec for Reg snapshot
foreach(OptionData opt in optChain)
{
Contract con = new()
{
Symbol = "SPY",
Currency = "USD"
Exchange = "SMART",
Right = "C",
SecType = "OPT",
Strike = opt.strike,
Expiry = opt.Expiry
};
ibClient.ClientSocket.reqMktData(opt.ReqId, con, "", false, true, new List<TagValue>());
}
}
...
private void Recv_TickPrice(TickPriceMessage msg)
{
if(optChain.ContainsKey(msg.RequestId))
{
if (msg.Field == 2) optChain[msg.RequestId].Ask = msg.Price;
if (msg.Field == 1) optChain[msg.RequestId].Bid = msg.Price;
// You may want other tick types as well
// see https://interactivebrokers.github.io/tws-api/tick_types.html
if(optChain[msg.RequestId].IsComplete())
{
// This wont apply for reg snapshot.
ibClient.ClientSocket.cancelMktData(msg.RequestId);
// You have the data, and have cancelled the request.
// Maybe request more data or update display etc...
// Check if the whole chain is complete
bool complete=true;
foreach(OptionData opt in optChain)
if(!opt.IsComplete()) complete=false;
if(complete)
// do whatever
}
}
}
I am using the below code to do the authorizatin checks.
PDPrincipal whoIsit = new PDPrincipal(userId,configURL);
PDPermission whatTheyWant = new PDPermission(objectSpaceName,"TbvA");
boolean haveAccess = whoIsit.implies(whatTheyWant);
However the implies method on com.tivoli.mts.PDPrincipal has been deprecated and has been replaced by implies method from the new PdPrincipal class from different package.
com.tivoli.pd.jazn.PDPrincipal
the new method is as follows.
public boolean implies(javax.security.auth.Subject subject)
the new method takes a Subject.
Can you please let me know how can I change my code to use the new method? How do i construct the Subject or can i get the Subject from somewhere?
Thanks,
Rohit
I was able to work out a solution for this hence sharing it here so that anyone else facing the same issue can use this code.
I found that the new com.tivoli.pd.jazn.PDPermission class has a method implies which takes in a PdAuthorization context and a com.tivoli.pd.jazn.PDPrincipal object which does the same authorization checks that the previous class com.tivoli.mts.PDPrincipal use to do.
Mentioned below is how the same authorization can be done. With this code you need not implement the JAAS code.
First construct the PdAuthorizationContext as shown below. Make sure to define a static PdAuthorizationContext object so that it can be reused untill you close it. Constructing PDAuthorizationContext for every authorization check is resource intensive and not recommended. close the context at the end of your logic
URL configURL = new URL("file:" + String locationToTamConfigFile);
PDAuthorizationContext pdAuthCtx = new PDAuthorizationContext(configURL);
Next Construct the new PDPrincipal and the PdPermission objects as shown below and call the implies method
com.tivoli.pd.jazn.PDPrincipal pdPrincipal = new com.tivoli.pd.jazn.PDPrincipal(pdAuthCtx,userId);
com.tivoli.pd.jazn.PDPermission pdPermission = new com.tivoli.pd.jazn.PDPermission(objectSpaceName,"TbvA");
boolean newimpliesTry = pdPermission.implies(pdAuthCtx,pdPrincipal);
I have this constructor:
public Revaluator(File model,PrintStream ps) {
modelFile=model;
rsession=Rsession.newInstanceTry(ps, null);
rsession.eval("library(e1071)");
rsession.load(modelFile);
}
i want to load a model and predict with it.
the problem that Rsession.newInstanceTry(ps, null); is always the same session, so if i load another model, like:
Revaluator re1=new Revaluator(new File("model1.RData"),System.out);
Revaluator re2=new Revaluator(new File("model2.RData"),System.out);
Both re1 and re2 using the same model, since the var name is model, so only the last one loaded.
the evaluate function:
public REXP evaluate(Object[] arr){
String expression=String.format("predict(model, c(%s))", J2Rarray(arr));
REXP ans=rsession.eval(expression);
return ans;
}
//J2Rarray just creates a string from the array like "1,2,true,'hello',false"
i need to load about 250 predictors, is there a way to get every instance of Rsession as a new separated R Session?
You haven't pasted all of your code in your question, so before trying the (complicated) way below, please rule out the simple causes and make sure that your fields modelFile and rsession are not declared static :-)
If they are not:
It seems that the way R sessions are created is OS dependent.
On Unix it relies on the multi-session ability of R itself, on Windows it starts with Port 6311 and checks if it is still free. If it's not, then the port is incremented and it checks again, if it's free and so on.
Maybe something goes wrong with checking free ports (which OS are you working on?).
You could try to configure the ports manually and explicitly start different local R servers like this:
Logger simpleLogger = new Logger() {
public void println(String string, Level level) {
if (level == Level.WARNING) {
p.print("! ");
} else if (level == Level.ERROR) {
p.print("!! ");
}
p.println(string);
}
public void close() {
p.close();
}
};
RserverConf serverConf = new RserverConf(null, staticPortCounter++, null, null, null);
Rdaemon server = new Rdaemon(serverConf, this);
server.start(null);
rsession = Rsession.newInstanceTry(serverConf);
If that does not work, please show more code of your Revaluator class and give details about which OS you are running on. Also, there should be several log outputs (at least if the log level is configured accordingly). Please paste the logged messages as well.
Maybe it could also help to get the source code of rsession from Google Code and use a debugger to set a breakpoint in Rsession.begin(). Maybe this can help figuring out what goes wrong.
I want to store a Riak Pojo object with links in the database using the java. Eventhough the field type is Collection <RiakLink>, it keep throwing the same exception "riak links field must be Collection <RiakLink> ".
Code:
class Pojo{
public String name;
#RiakKey
public String key;
#RiakLinks
#JsonIgnore
public Collection<RiakLink> collection = new ArrayList<RiakLink>();
}
public class Riak2 {
public static void main(String[] args) throws RiakException {
IRiakClient client = RiakFactory.httpClient();
Pojo p = new Pojo();
p.name = "Pojo";
p.key = "First";
p.collection.add(new RiakLink("list","Second","next"));
client.fetchBucket("list").execute().store(p);
}
}
Exception : Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: riak links field must
be Collection <RiakLink> at com.basho.riak.client.convert.reflect.AnnotationCache.get(AnnotationCache.java:56)
Please give me a help
Thanks
I've tested this in both the current 1.1.3 and 1.4.2 versions of the client and can not reproduce this issue.
In addition, there's actually a unit test that ensures this works.
Looking though the history for AnnotationCache, I can't find where there was ever a bug regarding this since it was created about two years ago so that rules out you using an old version of the client that has a bug.
Given that, I would suggest rebuilding your project / rechecking that the code you list in your Q is what is actually being used. As shown, there's no problem with it.
Right now I'm doing this but it seems to not work right. Thanks for any help.
public static void submit(#Valid WrapSpec wrapSpec) {
if (validation.hasErrors()) {
render("#index", wrapSpec);
}
JPA.em().detach(wrapSpec);
wrapSpec.wrapSpecId = null;
WrapSpec wrapSpecNew = wrapSpec.merge();
}
If you are using Play's Model class in you object, they have an automatic autoincrement field named "id".
The only safe way to reassign this id would be to create a new object and copy all the properties (expect id) from the old object to the new one, and then save it. JPA will assign the new id.
Any other way may create database inconsistencies or unexpected behavior in JPA/Play.
Out of curiosity, why would you like to change the id once assigned? I don't see how it may be useful...