I've recently started exploring Graph databases (in particular Neo4j and OrientDB) and have come across a problem I can't seem to put my finger on.
I'm running a local installation of OrientDB (OrientDB Server v2.0-M3 is active.).
I'm using Tinkerpops to connect to, and run queries against, the graph.
I'm using Java and Spring on a local Tomcat 7 server.
Testing my API I'm using Postman on Chrome.
Here's my faulty GET method:
#RequestMapping(value = "/articles", method = RequestMethod.GET)
public
#ResponseBody
Vector<Article> list() {
OrientGraph graph = new OrientGraph("remote:/local/path/to/orientdb/databases/mydb", "user", "password");
FramedGraphFactory factory = new FramedGraphFactory();
FramedGraph manager = factory.create(graph);
Vector<Article> articles = new Vector<>();
try {
Iterable<Vertex> vertices = graph.getVerticesOfClass("Article", false);
Iterator<Vertex> it = vertices.iterator();
if (it.hasNext()) {
do {
Article a = (Article) manager.frame(it.next(), Article.class);
articles.add(a);
} while (it.hasNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
graph.shutdown();
}
return articles;
}
This generates the following error:
{
"timestamp": 1418562889304,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.http.converter.HttpMessageNotWritableException",
"message": "Could not write JSON: Database instance is not set in current thread. Assure to set it with: ODatabaseRecordThreadLocal.INSTANCE.set(db); (through reference chain: java.util.Vector[0]->$Proxy43[\"name\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Database instance is not set in current thread. Assure to set it with: ODatabaseRecordThreadLocal.INSTANCE.set(db); (through reference chain: java.util.Vector[0]->$Proxy43[\"name\"])",
"path": "/articles"
}
I've been trying to figure this out, trying the "fix" that the error suggests. I've also tried to use TransactionalGraph instead of OrientGraph.
Here's the catch... I'm also using a similar method for getting a single resource. This method only works if I'm using the "System.out.println", otherwise it fails with the same error.
#RequestMapping(value = "/article", method = RequestMethod.GET)
public
#ResponseBody
Article get(
#RequestParam(value = "number", required = true) long number
) {
TransactionalGraph graph = new OrientGraph("remote:/path/to/local/orientdb/orientdb/databases/mydb", "user", "password");
FramedGraphFactory factory = new FramedGraphFactory();
FramedGraph manager = factory.create(graph);
Article article = null;
try {
Iterable<Article> articles = manager.getVertices("number", number, Article.class);
article = articles.iterator().next();
System.out.println(article.getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
graph.shutdown();
}
return article;
}
Any help appreciated!
You should leave the graph (=connection) open while you're using the result. Can you move the graph.shutdown() after browsing your result set?
Related
I try to use the gradle exemple to get googlessheets cells and get error with the tab name with diacritics ("Opérations 2023") because the name is in french.
https://developers.google.com/sheets/api/quickstart/java
the error is below.
{
"code": 400,
"errors": [
{
"domain": "global",
"message": "Unable to parse range: Op%C3%A9rations%202023!A2%3AE2",
"reason": "badRequest"
}
],
"message": "Unable to parse range: Op%C3%A9rations%202023!A2%3AE2",
"status": "INVALID_ARGUMENT"
}
The request is
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
final String spreadsheetId = "ID";
final String range = "Opérations 2023!A2:E2";
Sheets service =
new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
ValueRange response = service.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values == null || values.isEmpty()) {
System.out.println("No data found.");
} else {
System.out.println("Name, Major");
for (List row : values) {
// Print columns A and E, which correspond to indices 0 and 4.
System.out.printf("%s, %s\n", row.get(0), row.get(4));
}
}
}
}
What can I do please ?
I'm writing this answer as a community wiki, since the issue was resolved from the comments section, in order to provide a proper response to the question.
I tested with Sheets API Method: spreadsheets.values.get and I had no issues using it with sheet named "Opérations 2023" so it seems is not issue with the API but character encoding in Java.
I'm not an expert in Java, but while doing research, I found a similar thread and it shows the same error when using Java while doing it with Python it seems to work with no issue.
As a workaround, if the sheet you're aiming to is the first one in your Worksheet, then you can just omit the name of the Sheet and set the range to: "A2:E2", this will aim the default sheet which is the first one in your Worksheet.
I am trying to create a custom API Gateway lambda authorizer using Spring Cloud Function.
But when I am trying to return policy document as Map<String,Object> from Spring Function, Spring returning it as body along with some extra metadata. So ApiGateway treating it as invalid json. How to return only policy document.
This is what the String Function returning when I return Map<String,Object>. My Map Object data is in body.
{
"isBase64Encoded":false,
"headers":{
"id":"6b9da9d5-23a7-b555-aecf-90e6134779b8",
"contentType":"application/json",
"timestamp":"1630300611676"
},
"body":"{\"policyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn-value\",\"Effect\":\"Allow\"}]},\"context\":{\"name\":\"test\"},\"principalId\":\"813bf219-6039-4065-bcce-3e03b6996872\"}",
"statusCode":200
}
But it should actually return only body part for ApiGateway to work correctly.
{
"policyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Action":"execute-api:Invoke",
"Resource":"arn-value",
"Effect":"Allow"
}
]
},
"context":{
"name":"test"
},
"principalId":"813bf219-6039-4065-bcce-3e03b6996872"
}
My Spring Cloud Function code is below. It is only test function without proper logic.
#Bean
public Function<APIGatewayProxyRequestEvent, Map<String,Object>> authorise() {
return request -> {
String token = request.getHeaders().get("Authorization");
String arn = String.format("arn:aws:execute-api:%s:%s:%s/%s/%s/",
System.getenv("AWS_REGION"),
request.getRequestContext().getAccountId(),
request.getRequestContext().getApiId(),
request.getRequestContext().getStage(),
request.getRequestContext().getHttpMethod());
// Policy policy = jwtToken.getPolicy(token, arn);
try{
String allow = request.getHttpMethod().equalsIgnoreCase("GET")?"Allow":"Deny";
JSONObject json = new JSONObject();
json.put("principalId", UUID.randomUUID().toString())
.put("policyDocument",
new JSONObject()
.put("Version", "2012-10-17")
.put("Statement",
new JSONArray()
.put(new JSONObject()
.put("Action", "execute-api:Invoke")
.put("Effect", allow)
.put("Resource", arn)
)
)
)
.put("context", new JSONObject().put("name", "test"));
return json.toMap();
}catch(Exception e){
logger.error("",e);
}
return null;
};
}
I'm new to quarkus and reactive programming. I'm currently facing an issue with quarkus-reactive-postgresql extension.
I have a list containing events that perform a database update. Each event has to be updated independently (so I don't use a transaction).
Here is my web service:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Uni<JsonObject> synchro(List<Event> events) {
List<Uni<RowSet<Row>>> queries = new ArrayList<>();
List<Event> success = new ArrayList<>();
List<Event> fails = new ArrayList<>();
for (Event evt : events) {
// Perform update
var query = client.preparedQuery("My failing query")
.execute(Tuple.of(evt.field));
// Subscribe. It's ok. Add event to success list
query.subscribe().with(unused -> success.add(evt));
// It's failure. Add event to failures
query.onFailure(throwable -> {
log.error(String.format("Unable to update event %s", evt.toString()), throwable);
fails.add(evt);
return true;
});
queries.add(query);
}
return Uni.combine().all().unis(queries)
.combinedWith(ArrayList::new)
.onItem().transform(list -> new JsonObject()
.put("success", success.stream().map(Event::toJson).collect(Collectors.toList()))
.put("errors", fails.stream().map(Event::toJson).collect(Collectors.toList()))
);
}
Quarkus reactive pg extension throws an exception :
2021-08-06 10:35:37,665 ERROR [io.qua.mut.run.MutinyInfrastructure] (vert.x-eventloop-thread-23) Mutiny had to drop the following exception: io.vertx.pgclient.PgException: { "message": "column \"fake_column\" of relation \"table\" does not exist", "severity": "ERROR", "code": "42703", "position": "18", "file": "analyze.c", "line": "2263", "routine": "transformUpdateTargetList" }
However, .onFailure is not triggered and ever fill my failures list.
Is it a bug or something goes wrong with my code ?
Thanks for your help,
In case someone is struggling with this as I did, you can try adding the following code:
.onFailure().transform(ex -> {
if (ex.getClass().equals(PgException.class)) {
//here you can do log and stuff
//in case, you only need to return this boolean you can create
//custom handler for your custom exception
return new CustomException(ex);
}else{
return new Exception(ex);
});
transform() function somehow lets you return an exception no matter what your method was supposed to return, here is some resource for it:
https://cescoffier.github.io/mutiny-doc-sandbox/getting-started/handling-failures
Concerning handling the exception, here is a source that really helped me: https://howtodoinjava.com/resteasy/resteasy-exceptionmapper-example/
I have a problem in my .NET Web API - I am just posting data in my table before I am checking Is the record already inserted in the table but I get this error:
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
This is my code:
[HttpPost]
[Route("api/tblProducts/AddToWishCart", Name = "GetAddWishCartList")]
public IHttpActionResult AddToWishCart(tblWishCart3 wishList)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IEnumerable<GetAllCartListByStatusAndUserPrdIdWeightId_Result> tblCartWishList = dbO.GetAllCartListByStatusAndUserPrdIdWeightId(wishList.Status, wishList.UserId, wishList.PrdId, wishList.Extra3).AsEnumerable();
if (tblCartWishList == null)
{
var AltAddress = dbO.AddWishCart4(wishList.UserId, wishList.PrdId, wishList.Name, wishList.Weight, wishList.MRP, wishList.SellingPrice, wishList.OffPerentage, wishList.Quantity, wishList.Status, wishList.AddDate, wishList.Pic1, wishList.Extra1, wishList.Extra2, wishList.Extra3, wishList.Extra4, wishList.Extra5, wishList.Extra6, wishList.Extra7, wishList.Extra8, wishList.Extra9, wishList.Extra10);
}
else
{
}
return CreatedAtRoute("GetAddWishCartList", new { id = wishList.UserId }, wishList);
}
I'm trying to search a Solr server from a webservice using SolrNet. I set up the connection in the global.asax: Startup.Init<ApartmentDoc>("http://192.168.0.100:8080/solr/");
I'm trying to query the server in a class file via:
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<ApartmentDoc>>();
var apartments = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string> {
{ "defType", "edismax" } ,
{ "fl", "*,score,_dist_:geodist() " } ,
{ "bf", "recip(geodist(),1,1000,1000)" } ,
{ "fq", string.Format("{{!geofilt d={0}}}", radius * 1.609344) } ,
{ "sfield", "Location" } ,
{ "pt", string.Format("{0},{1}", centerLat, centerLong) }
}
});
return apartments;
The error I'm getting is: Unable to read data from the transport connection: The connection was closed.
I've checked the logs in TomCat, and the request is going through and the results appear to have been returned.
Any ideas why I'm not getting the results back?
Thanks,
Drew
As the 'rows' parameter wasn't defined in your code, the request is likely timing out from trying to retrieve a large number of documents. As explained in the SolrNet documentation, always define pagination parameters.