500 Internal Server Error when querying index - neo4jclient

I am trying to get started with Neo4j and the Neo4jClient; the first thing I'm trying to attempt is to insert a series of nodes with a publication_number property. Before inserting each node, I want to check to ensure another node with the same publication number does not exist. To this end I created an index for publication_number, which I then query.
This is the code I have so far. (Obviously all the logic above has not been implemented, but I can't even get this to work.)
class Program
{
static void Main(string[] args)
{
var client = new GraphClient(new Uri("http://192.168.12.31:7474/db/data"));
client.Connect();
// create index
client.CreateIndex("publication_number_idx", new IndexConfiguration
{
Provider = IndexProvider.lucene,
Type = IndexType.exact
},
IndexFor.Node);
// create record
Record record1 = new Record { publication_number = "1" };
Record record2 = new Record { publication_number = "2" };
// add record1 to graph and index
var record1Ref = client.Create(record1);
client.ReIndex(record1Ref, new[] { new IndexEntry ("publication_number_idx") { { "publication_number", record1.publication_number } } });
Console.WriteLine("Added record1 at {0}", record1Ref.Id);
// add record2 to graph and index
var record2Ref = client.Create( record2,
new[] { new Cites(record1Ref) { Direction = RelationshipDirection.Outgoing } },
new[] { new IndexEntry("publication_number_idx") { {"publication_number", record2.publication_number } } });
Console.WriteLine("Added record2 at {0}", record2Ref.Id);
// 500 error here
client.QueryIndex<Record>("publication_number_idx", IndexFor.Node, #"START n=node:publication_number_idx(publication_number = ""2"") RETURN n;");
}
}
public class Cites : Relationship, IRelationshipAllowingSourceNode<Record>, IRelationshipAllowingTargetNode<Record>
{
public Cites(NodeReference targetNode)
: base(targetNode)
{
}
public const string TypeKey = "CITES";
public override string RelationshipTypeKey
{
get { return TypeKey; }
}
}
I appear to be successful in adding the notes and updating the index. I am able to query the index using Cypher in the Console; however, when I use the same Cypher query with the Neo4J Client I get a 500 Internal Server Error on the query.
Unhandled Exception: System.ApplicationException: Received an unexpected HTTP status when executing the request.
The response status was: 500 Internal Server Error
The response from Neo4j (which might include useful detail!) was: {
"exception" : "NullPointerException", "fullname" :
"java.lang.NullPointerException", "stacktrace" : [
"org.apache.lucene.util.SimpleStringInterner.intern(SimpleStringInterner.java:54)",
"org.apache.lucen e.util.StringHelper.intern(StringHelper.java:39)",
"org.apache.lucene.index.Term.(Term.java:38)", "org.apache.luce
ne.queryParser.QueryParser.getFieldQuery(QueryParser.java:643)",
"org.apache.lucene.queryParser.QueryParser.Term(QueryPa
rser.java:1436)",
"org.apache.lucene.queryParser.QueryParser.Clause(QueryParser.java:1319)",
"org.apache.lucene.queryPar
ser.QueryParser.Query(QueryParser.java:1245)",
"org.apache.lucene.queryParser.QueryParser.TopLevelQuery(QueryParser.java
:1234)",
"org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:206)",
"org.neo4j.index.impl.lucene.IndexType .query(IndexType.java:300)",
"org.neo4j.index.impl.lucene.LuceneIndex.query(LuceneIndex.java:227)",
"org.neo4j.server.re
st.web.DatabaseActions.getIndexedNodesByQuery(DatabaseActions.java:889)",
"org.neo4j.server.rest.web.DatabaseActions.get
IndexedNodesByQuery(DatabaseActions.java:872)",
"org.neo4j.server.rest.web.RestfulGraphDatabase.getIndexedNodesByQuery(R
estfulGraphDatabase.java:707)",
"java.lang.reflect.Method.invoke(Method.java:606)",
"org.neo4j.server.rest.security.Secu
rityFilter.doFilter(SecurityFilter.java:112)" ] } at
Neo4jClient.GraphClient.SendHttpRequest(HttpRequestMessage request,
String commandDescription, HttpStatusCode[] ex pectedStatusCodes) in
c:\TeamCity\buildAgent\work\f1c4cf3efbf1b05e\Neo4jClient\GraphClient.cs:line
137 at Neo4jClient.GraphClient.QueryIndex[TNode](String indexName,
IndexFor indexFor, String query) in c:\TeamCity\buildA
gent\work\f1c4cf3efbf1b05e\Neo4jClient\GraphClient.cs:line 1168 at
Antares.Program.Main(String[] args) in c:\Users\Yellick
Chris\Documents\Visual Studio 2012\Projects\Antares\Antare
s\Program.cs:line 41

I'm not sure what the 500 error is about, but the solution to getting your query to work is to remove the 'QueryIndex' call (which is obsolete) and replace it with the Cypher notation, so:
var query = client.Cypher
.Start(new {n = Node.ByIndexLookup("publication_number_idx", "publication_number", "2")})
.Return<Record>("n");
var results = query.Results;
The query used in 'QueryIndex' has a different format to yours, if you look at the Neo4jclient Index Documentation you'd need to replace things like the = with : and wrap with ' like so:
client.QueryIndex<Record>("publication_number_idx", IndexFor.Node, #"START n=node:publication_number_idx('publication_number: ""2""') RETURN n;");
Not that that fixes the 500 error.

Related

"Failed to issue Dequeue" when using Twilio Task Router for non-phone related tasks

NOTE: Code snippets below are functional. The "dequeue" error mentioned in this post was based on an existing Assignment Callback external to these scripts. Once the URL was removed and the reservation.dequeue moved to this code, the error was resolved.
We are in the process of developing a chat application using Conversations between two people. I currently have it "wired" up with the following steps when a user initiates the chat:
Conversation is created.
User is created.
User is added to the conversation.
Task is created with conversation meta-data in attributes.
(followed by steps on the other user's session to accept the reservation, etc.)
These steps work as expected, but a "40140 - Failed to issue Dequeue instruction due to missing 'call_sid' property" is generated since the task isn't an incoming phone call. I tried putting the task into the "SMS" Task Channel, but that didn't stop the error.
I couldn't find any specific documentation on creating non-phone call-based tasks so I might be setting up the task routing incorrectly.
Here are code snippets showing how I create (in .NET) the conversation, user, and task, and how I accept (in TaskRouter.js) the reservation.
/***********************************************************************************************************
This code is server-side in .NET
***********************************************************************************************************/
public ConversationCredentials CreateConversation( string program, string name )
{
var memberId = DateTime.Now.ToString( "yyyyMMdd" ); // Temporary
TwilioClient.Init( _twilioAccountSid,_twilioAuthToken );
// If we decide to keep conversations on Twilio, we should replace the memberid with phiid, since member id might change
var conversation = ConversationResource.Create(
friendlyName: memberId + "_" + DateTime.Now.ToString( "HHmmss" )
);
var conversationCredentials = JoinConversation( conversation.Sid, name );
var taskSid = CreateTask( program, conversation.Sid, memberId );
conversationCredentials.taskSid = taskSid;
return conversationCredentials;
}
public ConversationCredentials JoinConversation( string conversationSid, string name )
{
var identity = name + "_" + DateTime.Now.ToString( "HHmmss" ); // Makes sure the user is unique, in case it's an employee joining more than one chat session)
TwilioClient.Init( _twilioAccountSid,_twilioAuthToken );
var participant = ParticipantResource.Create(
pathConversationSid: conversationSid,
identity: identity
);
var user = UserResource.Update(
pathSid: identity,
friendlyName: name
);
var token = GetJWT( _twilioConversationServiceSid, name ); // Conversation Service Sid
var conversationCredentials = new ConversationCredentials();
conversationCredentials.token = token;
conversationCredentials.conversationSid = conversationSid;
conversationCredentials.participantSid = participant.Sid;
conversationCredentials.participantName = name;
conversationCredentials.participantIdentity = participant.Identity;
return conversationCredentials;
}
public string CreateTask( string program, string conversationSid, string memberId )
{
TwilioClient.Init( _twilioAccountSid, _twilioAuthToken );
var attributes = JsonConvert.SerializeObject( new Dictionary<string,Object>()
{
{"conversationSid", conversationSid },
{"memberId", memberId },
{"program", program },
{"call_sid", "CHAT" }
}, Formatting.Indented);
var task = TaskResource.Create(
attributes: attributes,
workflowSid: _twilioWorkflowSid,
pathWorkspaceSid: _twilioWorkspaceSid_Nurses,
taskChannel: "Default"
);
return task.Sid;
}
/***********************************************************************************************************
This code is browser-side using TaskRouter.js
NOTE: This handles both voice (works fine) and conversations (the part in question)
***********************************************************************************************************/
registerTaskRouterCallbacks( _this ) : void {
this.worker.on('ready', function(worker) {
_this.updateButton( worker.activityName, "" );
});
this.worker.on("reservation.created", function(reservation) {
if ( reservation.task.attributes.type != "CHAT" )
{
_this.updateButton( "Call", reservation.task.attributes.from.replace( "+1", "" ) );
reservation.dequeue();
} else {
_this.updateButton( "Chat", reservation.task.attributes.memberId );
confirm("You have an incoming chat!");
reservation.accept();
// This is where the chat window would pop-up
}
});
this.worker.on("reservation.accepted", function(reservation) {
_this.worker.update({"ActivitySid": _this.activitySids["Busy"][0].sid});
_this.updateButton( "Busy", "" );
});
The "dequeue" error mentioned in this post was based on an existing Assignment Callback external to these scripts. Once the URL was removed and the reservation.dequeue moved to this code, the error was resolved.

Parsing Tweets with akka-streams

Im using the following code to connect to Twitter and get Tweets, however Im not able to create JsValue. If only map with byteString.utf8String I can see the strings. But when I add framing i get an error:
Read 7925 bytes which is more than 1000 without seeing a line terminator
No matter how long i make the input im still getting this error. What do I need to change to get a stream of JsValue in my websocket?
Information about how one is expected to consume twitter streams can be found here
#Singleton
class TwitterController #Inject() (ws: WSClient, conf: Configuration) {
def tweets = WebSocket.accept[JsValue,JsValue] { implicit request =>
Flow.fromSinkAndSource(Sink.ignore, queryToSource("cat"))
}
def queryToSource(keyword: String): Source[JsValue, NotUsed] = {
val url = "https://stream.twitter.com/1.1/statuses/filter.json"
credentials.map { case (consumerKey, requestToken) =>
val request = ws.url(url)
.sign(OAuthCalculator(consumerKey, requestToken))
.withQueryString("track" -> keyword)
.withMethod("GET")
streamResponse(request)
.via(Framing.delimiter(ByteString("\r\n"), maximumFrameLength = 1000, allowTruncation = true))
.map { byteString =>
Json.parse(byteString.utf8String)
// byteString.utf8String
}
} getOrElse {
Source.single(Json.parse("Twitter credentials missing"))
}
}
private def streamResponse(request:WSRequest): Source[ByteString, NotUsed] = Source.fromFuture(request.stream()).flatMapConcat(_.body)
lazy val credentials: Option[(ConsumerKey, RequestToken)] = for {
apiKey <- conf.getString("twitter.apiKey")
apiSecret <- conf.getString("twitter.apiSecret")
token <- conf.getString("twitter.token")
tokenSecret <- conf.getString("twitter.tokenSecret")
} yield (
ConsumerKey(apiKey, apiSecret),
RequestToken(token, tokenSecret)
)
}

AngularFire: How to update a $firebaseArray by extending the service and using the $$updated private method

I have two separate lists of Posts and Authors in my database, each Post containing an authorId to refer to the corresponding author.
The following method helps me retrieve the whole list of Posts by systematically including the name of the author for each Post:
app.factory('NormalizedPosts', function($firebaseArray, FirebaseFactory) {
var PostsWithAuthors = $firebaseArray.$extend({
// override $$added to include author name
$$added: function(snap) {
var record = $firebaseArray.prototype.$$added.call(this, snap);
FirebaseFactory.$getAuthorId( record.authorId ).$loaded(function( authorData ) {
record.authorData = authorData;
});
return record;
},
// ????????
$$updated: function(snap) {
var rec = $firebaseArray.prototype.$$updated.call(this, snap);
var updatedRecord = this.$getRecord(snap.key());
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
rec.authorData = authorData;
});
return rec;
}
});
return PostsWithAuthors;
});
PS: The FirebaseFactory is just a wrapper for firebase methods.
I then call
var list = new NormalizedPosts ( new Firebase(FBURL).child("posts") );
in my controller to get the full list. This works great.
I'm scratching my head with what should go into the $$updated method: When a new Post is added, the list gets updated as expected (through the $$added method). But when there's a change in a Post data (e.g. the post title), my list does not get updated, as I'm currently returning false in the $$updated method.
Question: What should go in the $$updated method so that when theres a change in a Post data, my list gets updated accordingly (and further returns the author's name!). Thanks
I think you're going through too many loops to get something simple done.
If the name of the author is "part of" the article than you should save it:
{
"articles": {
"firebase-uniq-id-1": {
"title": "My Writing Process",
"published": "2016-01-01",
"author": {
"firebase-uniq-id-2": "Ernest Hemingway"
}
}
},
"authors": {
"firebase-uniq-id-2": {
"name": "Ernest Hemingway",
"born": "1899-07-21",
"whatever": "Some Data"
}
}
}
When you'll want to show other details about the author, fetch it.
Edit:
If you still wish to use the extension option, I believe the only thing you're missing there is extending the updateRecord with rec:
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
updatedRecord.authorData = authorData;
angular.extend(updatedRecord, snap.val());
});
Also, in $$updated you need to return a boolean saying if the record changed or not, and not the record itself.
Keep in mind that if you go that path you shouldn't use the default $save() method of $firebaseArray since it will also save the full authorData
$$updated: function(snap) {
// boolean for the $$updated method
var rec = $firebaseArray.prototype.$$updated.call(this, snap);
// existing record as per this
var existingRecord = this.$getRecord(snap.key());
// record as per FB database
var updatedRecord = snap.val();
if ( rec ) {
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
updatedRecord.authorData = authorData;
angular.extend(existingRecord, updatedRecord);
});
} // end if loop
return rec;
}

403 error when trying to search twitter, Processing, Twitter4j, controlP5

When executing a twitter query i get a 403 error, the error message is below, however my other queries work perfectly and are executed prior to this one, can anyone spot what may be wrong here:
TWITTER EXCEPTION: TwitterException{exceptionCode=[f3acd3ed-00581fa3], statusCode=403, retryAfter=0, rateLimitStatus=null, version=2.1.5-SNAPSHOT(build: d372a51b9b419cbd73d416474f4a855f3e889507)}
this occurs when i execute a search from my app, im not overdoing the limits as i can execute my other searches perfectly its just this one, any help would be appreciated, the code is listed below. im using a combination of Twitter4j and Processing with controlP5 to handle the input like the search.
void setup(){
...
cp5.addTextfield("SEARCH")
.setPosition(30,20)
.setSize(100,20)
.setFocus(true)
.setColor(color(255,0,0))
.setGroup(g2)
;
}
public void SEARCH(String theText) {
qm.srch = true;
qm.theText = theText;
qm.userSearch();
qm.srch = false;
// automatically receives results from controller input
println("a textfield event for controller 'input' : "+theText);
}
void userSearch() {
try {
if (srch) {
ConfigurationBuilder cb9 = new ConfigurationBuilder();
cb9.setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXX");
cb9.setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx");
cb9.setOAuthAccessToken("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
cb9.setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
println("Connected");
Twitter twitter = new TwitterFactory(cb9.build()).getInstance();
Query srchh = new Query(theText2);
srchh.setRpp(5);
QueryResult srchhRes = twitter.search(srchh);
ArrayList srchhTwe = (ArrayList) srchhRes.getTweets();
for (int i = 0; i < srchhTwe.size(); i++) {
Tweet t = (Tweet) srchhTwe.get(i);
String user = t.getFromUser();
GeoLocation l = t.getGeoLocation();
String locNam = t.getLocation();
String msg = t.getText();
wholeTweetsL.add(msg);
println("\nMessage: " + msg);
println("\nLocation: " + locNam);
}
}
}
catch(TwitterException e) {
println("TWITTER EXCEPTION: " + e);
}
}
From twitter at https://dev.twitter.com/docs/error-codes-responses
403 Forbidden The request is understood, but it has been refused or access is not allowed. An accompanying error message will explain why. This code is used when requests are being denied due to update limits.

Trouble Creating JSON with MVC3 (asp.net) using static Json class (system.web.helpers.json)

I'm having trouble creating the following JSON using uisng the C# MVC3 system.web.helpers.json namespace. Here is what I am trying to form:
{"success":true,"msg":"", "Data": [ { "Id":167 } ] }
What I have tried is this (with no success)
var x = Json(
new {Id = result.SponsorListId});
return Json(new
{
success,
msg = success ? "" : "sponsorListResult Passed Into Update as null",
Data = new List<Json>() {x}
}, JsonRequestBehavior.DenyGet);
I've tried lots of other things also, but no point in listing all my failures.
Thanks for any help on this.
Basically all the Json() method does is serialize the object you send it. When you send it a List you are sending it a JsonResponse which isn't what you are intending. What you should do is:
return Json(new
{
success,
msg = success ? "" : "sponsorListResult Passed Into Update as null",
Data = new []{ new { Id: result.SponsorListId } }
}, JsonRequestBehavior.DenyGet);
Which should serialize out to where you want it to be.

Resources