OrientDB getVertices not working with Java-generated class/index - java

Summary
I'm playing around with OrientDB for a proof of concept, and I'm having some trouble querying a class/composite index generated through the Java API.
I created the class, added a few properties and generated the composite index using the API, then added a sample record. I verified that everything looked okay using the Studio. I then used getVertices(String label, String[] keys, Object[] values) to try to pull my sample record, but didn't get any results.
I purged the index and class and recreated them using the Studio UI, ran the getVertices code and the record was retrieved successfully.
In the course of my investigation, I also recreated the class/index using the Java API and provided an incorrect label (a class created via the UI that extended V) and the record was retrieved successfully, which was weird.
Why is the the Java-created class/index behaving differently than the one I made in the UI? Am I doing something wrong?
Environment Background
I'm using OrientDB Enterprise 2.0.3 and the 2.0.x orientdb-* and blueprints-core jars.
Details
I'm creating the class/index in Java kind of like this (shortened for simplicity, strings changed to protect the innocent):
//graph is an OrientGraph
//Create a new class that extends V
OClass vt = graph.createVertexType("MyClass", "V");
String[] props = {"first", "second", "third"}; //Property names
for(String prop : props)
vt.createProperty(prop, OType.STRING);
//Create unique composite index using all properties
vt.createIndex("myClass.myIndex", OClass.INDEX_TYPE.UNIQUE, props);
graph.commit();
I added records to the graph like this and confirmed that they showed up in Studio (select * from MyClass):
Vertex v = graph.addVertex("class:MyClass");
v.setProperty("first", "foo");
v.setProperty("second", "bar");
v.setProperty("third", "ed");
graph.commit();
To query the graph, I'm using this:
String[] keys = {"first", "second", "third"};
String[] values = {"foo", "bar", "ed"};
//Using getVertices to get records from a specific class with specified key values.
//There could be multiple classes with the same properties, so I have to be able
//to look for a set of properties within a specific class.
Iterable<Vertex> resultIterator = graph.getVertices("MyClass", keys, values);
for (Vertex v : resultIterator){
results.add(v); //Store result references for later use
}
Also, I did confirm that graph.isUseClassForVertexLabel() was true.
When I run graph.getVertices("MyClass",keys,values), nothing comes back.
If I run graph.getVertices("DummyClass",keys,values) where DummyClass is a random class created in Studio that extends V and has completely different properties than MyClass, I get results. This case kind of scares me, because there could eventually be multiple classes with the same properties, and I have to be able to query records from a specific class with a property set - I don't want to pull in results from a bunch of different classes...
If I recreate MyClass from the Studio UI and run graph.getVertices("MyClass",keys,values), I get the expected results.

I created an issue (#3889) for this on the OrientDB repo. It has been fixed.

Related

Getting All Workitems from Team Area

I have the following objects:
ITeamRepository repo;
IProjectArea projArea;
ITeamArea teamArea;
The process of obtaining the projArea and the teamArea is quite straightforward (despite the quantity of objects involved). However I can't seem to find a way to obtain a list with all the Workitems associated with these objects in a direct way. Is this directly possible, probably via the IQueryClient objects?
This 2012 thread (so it might have changed since) suggests:
I used the following code to get the work items associated with each project area:
auditableClient = (IAuditableClient) repository.getClientLibrary(IAuditableClient.class);
IQueryClient queryClient = (IQueryClient) repository.getClientLibrary(IQueryClient.class);
IQueryableAttribute attribute = QueryableAttributes.getFactory(IWorkItem.ITEM_TYPE).findAttribute(currProject, IWorkItem.PROJECT_AREA_PROPERTY, auditableClient, null);
Expression expression = new AttributeExpression(attribute, AttributeOperation.EQUALS, currProject);
IQueryResult<IResolvedResult<IWorkItem>> results = queryClient.getResolvedExpressionResults(currProject, expression, IWorkItem.FULL_PROFILE);
In my code, currProject would be the IProjectArea pointer to the current project as you loop through the List of project areas p in your code.
The IQueryResult object 'results' then contains a list of IResolvedResult records with all of the work items for that project you can iterate through and find properties for each work item.

How to store values from Trident/Storm in a List (using the Java API)

I'm trying to create a few Unit Tests to verify that certain parts of my Trident topology are doing what they are supposed to.
I'd like to be able to retrieve all the values resulting after running the topology and put them in a List so I can "see" them and check conditions on them.
FeederBatchSpout feederSpout = new FeederBatchSpout("some_time_field", "foo_id");
TridentTopology topology = new TridentTopology();
topology.newStream("spout1", feederSpout)
.groupBy(new Fields("some_time_field", "foo_id"))
.aggregate(new Fields("foo_id"), new FooAggregator(),
new Fields("aggregated_foos"))
// Soo... how do I retrieve the "aggregated_foos" from here?
I am running the topology as a TrackedTopology (got the code from another S.O. question, thank you #brianghig for asking it and #Thomas Kielbus for the reply)
This is how I "launch" the topology and how I feed sample values into it:
TrackedTopology tracked = Testing.mkTrackedTopology(cluster, topology.build());
cluster.submitTopology("unit_tests", config, tracked.getTopology());
feederSpout.feed(new Values(MyUtils.makeSampleFoo(1));
feederSpout.feed(new Values(MyUtils.makeSampleFoo(2));
When I do this, I can see in the log messages that the topology is running correctly, and that the values are calculated properly, but I'd like to "fish" the results out into a List (or any structure, at this point) so I can actually put some Asserts in my tests.
I've been trying [a s**ton] of different approaches, but none of them work.
The latest idea was adding a bolt after the aggregation so it would "persist" my values into a list:
Below you'll see the class that tries to go through all the tuples emitted by the aggregate and would put them in a list that I had previously initialized:
class FieldFetcherStateUpdater extends BaseStateUpdater<FieldFetcherState> {
final List<AggregatedFoo> results;
public FieldFetcherStateUpdater(List<AggregatedFoo> results) {
this.results = results;
}
#Override
public void updateState(FieldFetcherState state, List<TridentTuple> tuples,
TridentCollector collector) {
for (TridentTuple tuple : tuples) {
results.add((AggregatedFoo) tuple.getValue(0));
}
}
}
So now the code would look like:
// ...
List<AggregatedFoo> results = new ArrayList();
topology.newStream("spout1", feederSpout)
.groupBy(new Fields("some_time_field", "foo_id"))
.aggregate(new Fields("foo_id"), new FooAggregator(),
new Fields("aggregated_foos"))
.partitionPersist(new FieldFetcherFactory(),
new Fields("aggregated_foos"),
new FieldFetcherStateUpdater(results));
LOGGER.info("Done. Checkpoint results={}", results);
But nothing... The logs show Done. Checkpoint results=[] (empty list)
Is there a way to get that? I imagine it must be doable, but I haven't been able to figure out a way...
Any hint or link to pages or anything of the like will be appreciated. Thank you in advance.
You need to use a static member variable result. If you have multiple parallel tasks running (ie, parallelism_hint > 1) you also need to synchronize the write access to result.
In your case, result will be empty, because Storm internally, creates a new instance of your bolt (including a new instance of ArrayList). Using a static variable ensures, that you get access to the correct object (as there will be only one over all instances of your bolt).

List of Places using Platform SDK

Background
My application connects to the Genesys Interaction Server in order to receive events for actions performed on the Interaction Workspace. I am using the Platform SDK 8.5 for Java.
I make the connection to the Interaction Server using the method described in the API reference.
InteractionServerProtocol interactionServerProtocol =
new InteractionServerProtocol(
new Endpoint(
endpointName,
interactionServerHost,
interactionServerPort));
interactionServerProtocol.setClientType(InteractionClient.AgentApplication);
interactionServerProtocol.open();
Next, I need to register a listener for each Place I wish to receive events for.
RequestStartPlaceAgentStateReporting requestStartPlaceAgentStateReporting = RequestStartPlaceAgentStateReporting.create();
requestStartPlaceAgentStateReporting.setPlaceId("PlaceOfGold");
requestStartPlaceAgentStateReporting.setTenantId(101);
isProtocol.send(requestStartPlaceAgentStateReporting);
The way it is now, my application requires the user to manually specify each Place he wishes to observe. This requires him to know the names of all the Places, which he may not necessarily have [easy] access to.
Question
How do I programmatically obtain a list of Places available? Preferably from the Interaction Server to limit the number of connections needed.
There is a method you can use. If you check methods of applicationblocks you will see cfg and query objects. You can use it for get list of all DNs. When building query, try blank DBID,name and number.
there is a .net code similar to java code(actually exatly the same)
List<CfgDN> list = new List<CfgDN>();
List<DN> dnlist = new List<Dn>();
CfgDNQuery query = new CfgDNQuery(m_ConfService);
list = m_ConfService.RetrieveMultipleObjects<CfgDN>(query).ToList();
foreach (CfgDN item in list)
{
foo = (DN) item.DBID;
......
dnlist.Add(foo);
}
Note : DN is my class which contains some property from platform SDK.
KeyValueCollection tenantList = new KeyValueCollection();
tenantList.addString("tenant", "Resources");
RequestStartPlaceAgentStateReportingAll all = RequestStartPlaceAgentStateReportingAll.create(tenantList);
interactionServerProtocol.send(all);

Upsert for LDAP directory in Java

I'm attempting to execute an Upsert using the Novell JLDAP library, unfortunately, I'm having trouble finding an example of this. Currently, I have to:
public EObject put(EObject eObject){
Subject s = (Subject) eObject;
//Query and grab attributes from subject
LDAPAttributes attr = resultsToAttributes(getLDAPConnection().get(s));
//No modification needed - return
if(s.getAttributes().equals(attr)){
return eObject;
} else {
//Keys:
//REPLACE,ADD,DELETE, depending on which attributes are present in the maps, I choose the operation which will be used
Map<String,LDAPAttribute> operationalMap = figureOutWhichAttributesArePresent(c.getAttributes(),attr);
//Add the Modifcations to a modification array
ArrayList<LDAPModification> modList = new ArrayList<LDAPModification>();
for(Entry entry: operationalMap.getEntrySet()){
//Specify whether it is an update, delete, or insert here. (entry.getKey());
modList.add(new LDAPModification(entry.getKey(),entry.getValue());
}
//commit
connection.modify("directorypathhere",modList.toArray(new LDAPModification[modList.size()]));
}
I'd prefer to not have to query on the customer first, which results in cycling through the subject's attributes as well. Is anyone aware if JNDI or another library is able to execute an update/insert without running multiple statements against LDAP?
Petesh was correct - the abstraction was implemented within the Novell library (as well as the UnboundId library). I was able to "upsert" values using the Modify.REPLACE param for every attribute that came in, passing in null for empty values. This effectively created, updated, and deleted the attributes without having to parse them first.
In LDAP, via LDIF files, an upset would be a single event with two steps. A remove and add of a value. This is denoted by a single dash on a line, between the remove then the add.
I am not sure how you would do it in this library. I would would try to modList.remove and then modList.add one after another and see if that works.

Find Universe meta Data Information in BO SDK R4

I am new to BO, I need to find universe name and the corresponding metadata information like(Table name, column names, join conditions etc...). I am unable to find proper way to start. I looked with Data Access SDK, Semantic SDk.
Can any one please provide me the sample code or procedure for starting..
I googled a lot but i am unable to find any sample examples
I looked into this link but that code will work only on R2 Server.
http://www.forumtopics.com/busobj/viewtopic.php?t=67088
Help is Highly Apprecitated.....
Assuming you're talking about IDT based universes, you'll need to code some Java. The JavaDoc for the API is available here.
In a nutshell, you do something like this:
SlContext context = SlContext.create() ;
LocalResourceService service = context.getService(LocalResourceService.class) ;
String blxFile = service.retrieve("universe.unx","output directory") ;
RelationalBusinessLayer businessLayer = (RelationalBusinessLayer)service.load(blxFile);
RootFolder rootFolder = businessLayer.getRootFolder() ;
Once you have a hook on the rootFolder, you can use the getChildren() method to drill into the folder structure and access the various subfolders/business objects available.
You may also want to check the CmsResourceService class to access universes stored on the repository.
To get the information you are after will require a 2 part solution. Part 1 use the Rebean SDK looking at WebI reports for the Universe and object names being used with in it.
Part 2 is to break out your favorite COM programming tool, since I try to avoid COM I use the Excel Macro editor, and access the BusinessObjects Designer library. Main code snippets that I currently have are:
Dim boUniv As Designer.Universe
Dim tbl As Designer.Table
For Each tbl In boUniv.Tables
Debug.Print tbl.Name
Next tbl
This prints all of the tables in a universe.
You will need to combine the 2 parts on your own for a dependency list between WebI reports and Universes.

Categories