How to decode the OpenLR string in a HERE Traffic API v7 response? - here-api

I'm currently building a client that requests Traffic Flow data from the Traffic API v7:
https://data.traffic.hereapi.com/v7/flow?locationReferencing=olr&…
I would like to decode the OpenLR Location Referencing string contained in the response, but I'm not using Java nor Scala so I cannot use the libraries provided.
Returned strings look like this:
"olr": "CCoBEAAmJQm+WSVVfAAJBQQCAxoACgUEAogZAAHtA2UACQUEAgOEADBigj0="
I've read the paragraph on the difference between TISA OLR and TomTom OpenLR, and I am able to find online decoders for the TomTom OpenLR strings as well as some libraries in various languages; but none of those work for the OpenLR string that the HERE API returns.
Are there any resources (source code, online decoders, further documentation) that have details on decoding OpenLR strings used by HERE?

HERE Location Lib would do it for you.
import com.here.platform.location.referencing.olr.OlrPrettyPrinter;
import com.here.platform.location.tpeg2.BinaryMarshallers;
import com.here.platform.location.tpeg2.olr.LinearLocationReference;
import com.here.platform.location.tpeg2.olr.OpenLRLocationReference;
import java.io.ByteArrayInputStream;
import java.util.Base64;
public class decode {
public static void main(final String[] args) {
byte[] decode = Base64.getDecoder().decode("CCoBEAAmJQm+WSVVfAAJBQQCAxoACgUEAogZAAHtA2UACQUEAgOEADBigj0=");
OpenLRLocationReference reference =
BinaryMarshallers.openLRLocationReference()
.unmarshall(new ByteArrayInputStream(decode));
System.out.println(OlrPrettyPrinter.prettyPrint((LinearLocationReference) reference.getLocationReference()));
}
}
output below:
type: OLR LinearLocationReference
positiveOffset: DistanceMetresMax15000(98)
negativeOffset: DistanceMetresMax15000(317)
firstReferencePoint:
coordinate: 2446716,638553 => 52.50083,13.701861
lineProperties:
bearing: 26 => 36.6°
frc: 2 (0-7, with 0 most important)
fow: 3 => single carriageway
pathProperties:
lfrcnp: 2 (0-7, with 0 most important)
dnp: 1049 m
againstDrivingDirection: false
intermediateReferencePoints: ∅
lastReferencePoint:
coordinate: 869,493 => 52.50952,13.706791
lineProperties:
bearing: 132 => 185.6°
frc: 2 [0-7], with 0 most important
fow: 3 => single carriageway

Related

How I set up an Web Api end point hosted directly on Xamarin Forms?

I would like to expose an http server on my xamarin forms app to expose data outside the phone, is it possible ? For example, an endpoind which returns log file inside phone. thank you
Yes it is possible. We are using EmbedIO.
Take a look at this github repo.
You can create your webserver like (basic example)
var server = new WebServer(o => o
.WithMode(HttpListenerMode.EmbedIO))
.WithLocalSessionManager()
.WithWebApi("/api", m => m.WithController(() => new YourController()));
public class YourController : WebApiController
{
[Route(HttpVerbs.Get, "/test")]
public Task<string> Get()
{
return Task.FromResult("test");
}
}
Ofc you need to know device IP address. Then you can set it for example
_server = new WebServer(o => o
.WithUrlPrefixes($"http://yourIp:8088")
...

Rackspace CloudFile API - get object information

So, here's what I'm doing with the API:
Auth (to get token and publicUrl for the particular region I need from the "object-store")
Use the publicUrl from the endpoint like so to get a list of files:
GET [publicUrl]/[container]
This returns an array where each item (object) looks like the following:
(
[hash] => 7213ee9a7d9dc119d2921a40e899ec5e
[last_modified] => 2015-12-29T02:46:08.400490
[bytes] => 1
[name] => Some type of file name.jpg
[content_type] => application/postscript
)
Now, how do I build the url to do a GET on the item (object)? I've tried the following:
[publicUrl]/[container]/[hash]
[publicUrl]/[container]/urlencoded([name])
among other things that don't make sense, but I tried anyway.
Any thoughts/help would be appreciated!
If you are using a Rackspace SDK, you can skip building the URLs yourself.
Here is the documentation for retrieving a Cloud Files object using a public URL. The object URL is the combination of the public URL of the container (found in the X-Cdn-Uri response header) with the object name appended.
For example, for a container named 'foo', send an authenticated HEAD request to the API:
HEAD {cloudFilesEndpoint}/foo
In the response, the container's public URL is in the 'X-Cdn-Uri' header:
HTTP/1.1 204 No Content
X-Cdn-Ssl-Uri: https://83c49b9a2f7ad18250b3-346eb45fd42c58ca13011d659bfc1ac1.ssl.cf0.rackcdn.com
X-Ttl: 259200
X-Cdn-Uri: http://081e40d3ee1cec5f77bf-346eb45fd42c58ca13011d659bfc1ac1.r49.cf0.rackcdn.com
X-Cdn-Enabled: True
X-Log-Retention: False
X-Cdn-Streaming-Uri: http://084cc2790632ccee0a12-346eb45fd42c58ca13011d659bfc1ac1.r49.stream.cf0.rackcdn.com
X-Trans-Id: tx82a6752e00424edb9c46fa2573132e2c
Content-Length: 0
Now, for an object named 'styles/site.css', append that name to the public URL, resulting in the following URL:
http://081e40d3ee1cec5f77bf-346eb45fd42c58ca13011d659bfc1ac1.r49.cf0.rackcdn.com/styles/site.css

Jasypt with the Bouncy Castle JCE SHA512 encryption

I need:
password based encryption using sha512 digesting and 256 bit AES encryption with cbc and bc flags set.
Seems that algorithm should be like this: PBEWithSHA512AndAES256-CBC-BC
but in my local env I get error: org.jasypt.exceptions.EncryptionInitializationException: java.security.NoSuchAlgorithmException: no such algorithm: PBEWithSHA512AndAES256-CBC-BC for provider BC
my test code:
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
public class App {
static {
Security.addProvider(new BouncyCastleProvider());
}
public static void main(String[] args) {
StandardPBEStringEncryptor mySecondEncryptor = new StandardPBEStringEncryptor();
mySecondEncryptor.setProviderName("BC");
// mySecondEncryptor.setAlgorithm("PBEWITHSHA256AND128BITAES-CBC-BC");
mySecondEncryptor.setAlgorithm("PBEWithSHA512AndAES256-CBC-BC");
mySecondEncryptor.setPassword("pass");
String myText = "Mindaugas";
String mySecondEncryptedText = mySecondEncryptor.encrypt(myText);
System.out.println(mySecondEncryptedText);
System.out.println(mySecondEncryptor.decrypt(mySecondEncryptedText));
}
}
PBEWITHSHA256AND128BITAES-CBC-BC - this algorithm works fine but I need sha512 and 256 bit AES...
I have installed extensions form: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
but still get this error: no such algorithm
Since the list of algorithms on the bouncycastle website is not updated, looking at the code in the constructor in the Java file BouncyCastleProvider.java, you can find an exhaustive list of algorithms which are supported by bcprov-jdk16. A small list (of the type of algorithms/functions you were looking for) supported is -
PBEWITHSHAAND128BITAES-CBC-BC
PBEWITHSHAAND192BITAES-CBC-BC
PBEWITHSHAAND256BITAES-CBC-BC
PBEWITHSHA256AND128BITAES-CBC-BC
PBEWITHSHA256AND192BITAES-CBC-BC
PBEWITHSHA256AND256BITAES-CBC-BC
PBEWITHSHA1AND128BITAES-CBC-BC
PBEWITHSHA1AND192BITAES-CBC-BC
PBEWITHSHA1AND256BITAES-CBC-BC
PBEWITHSHA-1AND128BITAES-CBC-BC
PBEWITHSHA-1AND192BITAES-CBC-BC
PBEWITHSHA-1AND256BITAES-CBC-BC
PBEWITHSHA-256AND128BITAES-CBC-BC
PBEWITHSHA-256AND192BITAES-CBC-BC
PBEWITHSHA-256AND256BITAES-CBC-BC

Spring-boot return json and xml from controllers

I have a spring-boot 1.1.7 application that uses Thymeleaf for much of the UI, so the response from my controllers hasn't really been a concern. However, now I need to provide a XML response when a user submits a request via URL.
Here is a typical Request:
http://localhost:9001/remote/search?sdnName=Victoria&address=123 Maple Ave
Here is most of my gradle configuration:
project.ext {
springBootVersion = '1.1.7.RELEASE'
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
compile("org.springframework.security:spring-security-web:4.0.0.M1")
compile("org.springframework.security:spring-security-config:4.0.0.M1")
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:2.1.1.RELEASE')
compile("org.springframework.boot:spring-boot-starter-actuator")
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.0')
}
And here is my controller:
#Controller
public class RemoteSearchController {
#Autowired
private SdnSearchService sdnSearchService;
#RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
public List<Sdn> search(#ModelAttribute SdnSearch sdnSearch) {
List<Sdn> foundSdns = sdnSearchService.find( sdnSearch );
return foundSdns;
}
Here is my Object to be returned:
#Entity
public class Sdn {
#Id
private long entNum;
private String sdnName;
...
//getters & setters here
}
I am able to receive the request via REST client (such as CocoaREST) and handle it. But When I return the list of SDN i get the following exception, even though I do have Jackson & jackson-dataformat-xml on my classpath:
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:229)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:301)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:248)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:57)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:299)
My REST Client is including a Accept Header of "text/xml" (but in all honesty I would rather them not have to set this. Ideally any call to this Controller would always get XML, regardless of header being present).
Is there a way to handle this? I thought the Media Converters were included and just returned whatever the controller told them to?
SOLUTION:
See below for the answer I posted.
I had the exact same problem and I found the solution on Spring documentation website : here
In synthesis, I added the following dependency to the pom.xml of my project :
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Then I added the following code block to the class that the service had to return :
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Greeting {...}
And it worked.
SOLUTION: I used a combination of both answers below (thank you very much!). I am posting here in case anyone else needs help.
My modified controller:
#Controller
public class RemoteSearchController {
#Autowired
private SdnSearchService sdnSearchService;
#RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = { "application/xml", "text/xml" }, consumes = MediaType.ALL_VALUE )
#ResponseBody
public SdnSearchResults search(#ModelAttribute SdnSearch sdnSearch) {
List<Sdn> foundSdns = sdnSearchService.find( sdnSearch );
SdnSearchResults results = new SdnSearchResults();
results.setSdns( foundSdns );
return results;
}
}
And on my client, I set the request headers:
Content-type: application/text
Accept: text/xml
I think ultimately the problem was that my client headers were not being set correctly, so I may not have had to make some of these changes. But I liked the idea of a SearchResults class containing a list of results:
#XmlRootElement
public class SdnSearchResults {
private List<Sdn> sdns;
...
}
It may be better to create a new class:
public class SdnSearchResult {
private List<Sdn> sdns;
...
}
Then, a slight change will be required to the existing classes as follows:
public interface SdnSearchService {
SdnSearchResult find(SdnSearch sdnSearch);
}
#Controller
public class UISearchController {
#Autowired
private SdnSearchService sdnSearchService;
#RequestMapping("/search")
public ModelAndView search(#ModelAttribute SdnSearch sdnSearch) {
return new ModelAndView("pages/search/results", "sdns", sdnSearchService.find(sdnSearch).getSdns());
}
}
Once this is done, the other controller must be coded as:
#Controller
public class RemoteSearchController {
#Autowired
private SdnSearchService sdnSearchService;
#RequestMapping("/remote/search")
#ResponseBody
public SdnSearchResult search(#RequestBody SdnSearch sdnSearch) {
return sdnSearchService.find(sdnSearch);
}
}
A quick explanation of the changes from your code:
#RequestBody will automatically deserialize the entire HTTP request body to an SdnSearch instance. External applications will typically submit the request data as HTTP body, so #RequestBody will ensure that the deserialization to Java object happens automatically.
#ResponseBody will automatically serialize the return value according to the external client's capabilities and the libraries available on the classpath. If Jackson is available on the classpath and the client has indicated that they can accept JSON, the return value will be automatically sent as JSON. If the JRE is 1.7 or higher (which means that JAXB is included with the JRE) and the client has indicated that they can accept XML, the return value will be automatically sent as XML.
List<Sdn> needs to be changed to SdnSearchResult to ensure that the application can exchange JSON, XML, RSS and ATOM formats with a single controller method, since XML (and XML based formats) require a root-tag on the output, which a List<Sdn> cannot be translated to.
Once these changes are done, fire up a REST client such as the Postman extension for Chrome and submit a request to /remote/search with the following information:
Request header Accepts set to application/json.
Request header Content-Type set to application/json.
Request body set to the JSON string { "sdnName" : "Victoria", "address" : "123 Maple Ave" }.
This will give you a JSON response.
You've marked the controller method as producing application/xml responses (produces = MediaType.APPLICATION_XML_VALUE). The request's accept header (Accept: text/xml) doesn't match so Spring determines that your search method cannot handle the request.
There are a few different ways to fix this on the server, depending on your exact requirements:
You could remove the produces attribute entirely
You could specify multiple media types: produces = { "application/xml", "text/xml" }
I am not sure about your version of Spring Boot (1.1.7.RELEASE) but I am on version 1.5.2.RELEASE and this xml conversion / serialization happens automatically without usage of any jackson dependencies as mentioned in few of the answers.
I guess that is happening because org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter is automatically configured since Spring Boot version 1.5.1.RELEASE & that converter uses default JAXB implementation of JRE ( so no explicit xml conversion dependency needed ) .
Second, Accept header set by clients in request decides which format the output is expected so a request mapping like below ( i.e. a single end point ) ,
#RequestMapping(method = RequestMethod.GET, value = "/remote/search", produces = {
MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE })
can be used to produce an xml as well as a JSON response ( if Accept header is set as text/xml or application/xml & application/json respectively.
Note 1 : javax.xml.bind.annotation.XmlRootElement needs to be specified on root class if xml response is expected for a Java class. This is mandatory.
Note 2 : Jackson for json is already included in Spring Boot so that is not to be explicitly included for json outputs
Note 3 : Accept header - Output match off happens automatically by framework & developer doesn't have to code anything specific for that.
So in my opinion, if you only add XmlRootElement to your base class & upgrade your Spring Boot version, your server side is all set. Responsibility to set correct Accept header lies with the clients.
In addition to what Michael told in his answer, I added the following dependencies as well to pom.xml
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.1</version>
</dependency>
For some reason, the jackson-dataformat-xml alone was not helping.
I also made sure that ResponseEntity is returned in the get call and removed the produces=MediaType from the RequestMapping annotation.
With these changes, I was able to get the correct data but I had to give the extension of mime type to the REST URL during get call. ie, specify explicitly like: http://localhost:8080/hello.xml or http://localhost:8080/hello.json in browser
In my case I wanted to return a formatted XML string and it was all combined into one line.
Adding produces = { "application/xml", "text/xml" } to the request mapping was enough to return the string as formatted XML (with indentation).
example:
#RequestMapping(method= RequestMethod.GET, value="/generate/{blabla}", produces = { "application/xml", "text/xml" })
public String getBlaBla(#PathVariable("param") String param) throws IOException {
}
Goodluck.

Is it a bad idea to use synchronous filesystem methods in a Dart web server?

I'm playing around with HttpServer; and was adding support for serving static files (I'm aware of Shelf; I'm doing this as a learning exercise). I have a list of handlers that are given the opportunity to handle the request in sequence (stopping at the first that handles it):
const handlers = const [
handleStaticRequest
];
handleRequest(HttpRequest request) {
// Run through all handlers; and if none handle the request, 404
if (!handlers.any((h) => h(request))) {
request.response.statusCode = HttpStatus.NOT_FOUND;
request.response.headers.contentType = new ContentType("text", "html");
request.response.write('<h1>404 File Not Found</h1>');
request.response.close();
}
}
However, as I implemented the static file handler, I realised that I couldn't return true/false directly (which is required by the handleRequest code above, to signal if the request is handled) unless I use file.existsSync().
In something like ASP.NET, I wouldn't think twice about a blocking call in a request because it's threaded; however in Dart, it seems like it would be a bottleneck if every request is blocking every other request for the duration of IO hits like this.
So, I decided to have a look in Shelf, to see how that handled this; but disappointingly, that appears to do the same (in fact, it does several synchronous filesystem hits).
Am I overestimating the impact of this; or is this a bad idea for a Dart web service? I'm not writing Facebook; but I'd still like to learn to write things in the most efficient way.
If this is considered bad; is there a built-in way of doing "execute these futures sequentially until the first one returns a match for this condition"? I can see Future.forEach but that doesn't have the ability to bail. I guess "Future.any" is probably what it'd be called if it existed (but that doesn't)?
Using Shelf is the right approach here.
But there is still a trade-off between sync and async within the static handler package.
Blocking on I/O obviously limits concurrency, but there is a non-zero cost to injecting Future into a code path.
I will dig in a bit to get a better answer here.
After doing some investigation, it does not seem that adding async I/O in the shelf_static improves performance except for the bit that's already async: reading file contents.
return new Response.ok(file.openRead(), headers: headers);
The actual reading of file contents is done by passing a Stream to the response. This ensures that the bulk of the slow I/O happens in a non-blocking way. This is key.
In the mean time, you may want to look at Future.forEach for an easy way to invoke an arbitrary number of async methods.
There are a lot of good questions in your post (perhaps we should split them out into individual SO questions?).
To answer the post title's question, the best practice for servers is to use the async methods.
For command-line utilities and simple scripts, the sync methods are perfectly fine.
I think it becomes a problem if you do file access that is blocking for a long time (reading/writing/searching big files locally or over the network).
I can't imagine file.existsSync() doing much damage. If you are already in async code it's easy to stay async but if you have to go async just for the sake of not using file.existsSync() I would consider this premature optimization.
A little offtopick, but it solved my problem, I was trying to solve by reading discussion on this question. I was not able to achieve async operation in handler with io.serve, so I used dart:io for active pages and shelf.handleReguest for static files:
import 'dart:io';
import 'dart:async' show runZoned;
import 'package:path/path.dart' show join, dirname;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';
import 'dart:async';
import 'package:sqljocky/sqljocky.dart';
void main(){
HttpServer
.bind(InternetAddress.ANY_IP_V4, 9999)
.then((server) {
server.listen((HttpRequest request) {
String path = request.requestedUri.path;
if(path == "/db"){
var pool = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', db: 'db', max: 5);
var result = pool.query("select * from myTable");
result.then((Results data) {
data.first.then((Row row) {
request.response.write(row.toString());
request.response.close();
});
});
}else{
String pathToBuild = join(dirname(Platform.script.toFilePath()), '..', 'build/web');
var handler = createStaticHandler(pathToBuild, defaultDocument: 'index.html');
io.handleRequest(request, handler);
}
});
});
}
Many months later I've found how to create that Stream... (still offtopick .. a little)
shelf.Response _echoRequest(shelf.Request request) {
StreamController controller = new StreamController();
Stream<List<int>> out = controller.stream;
new Future.delayed(const Duration(seconds:1)).then((_){
controller.add(const Utf8Codec().encode("hello"));
controller.close();
});
return new shelf.Response.ok(out);
}

Resources