FINAL EDIT: The answer has been found. It was a dependency issue. Read answer below.
I'm working on a program that eventually should push data from an SQL server db real-time to our power BI report. I'm currently at a stage where I try to connect to my power BI from my client app.
For the authentication process I've followed this example for the code: https://gist.github.com/dquig/a4f2f02fe3e306cebe2e The authentication seems to be working fine. I'm getting an accesstoken (which is the same everytime, I haven't found yet if this is as supposed to be). EDIT: I also checked all of the msdn pages for OAuth2, powerBI API (including the Azure Active Directory steps).
EDIT: I've just noticed I even get an accesstoken if I fill in complete nonsense (why didn't I try this before... ). What I get is the same token everytime. The Response for the webrequest has a 200 status but a null entity.
Here is my code for authentication (I've left out the request here):
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.microsoft.aad.adal4j.AuthenticationContext;
public class PowerBIController {
private static final String POWER_BI_BASE_URL = "https://api.powerbi.com";
private static final String AUTH_URI = "https://login.windows.net/common/oauth2/authorize";
private static final String RESOURCE_URI = "https://analysis.windows.net/powerbi/api";
private static final boolean VALIDATE_AUTHORITY = false;
private static final String NATIVE_CLIENT_ID = "4b2f0d69-c17d-4d61-b2c0-4aeee5dfffe8";
private static final String USER_AT_TENANT = "powerBIUser@pveermanvicrea.onmicrosoft.com";
private static final String PASSWORD = "****";
private AuthenticationContext context = null;
private Client client;
private ExecutorService service = null;
private Response response;
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
}
private String getToken(String resourceUri, String nativeClientId,
String tenant, String password) throws ExecutionException, InterruptedException{
return context.acquireToken(
resourceUri,
nativeClientId,
tenant,
password,
null
).get().getAccessToken();
}
Then comes the http request: I tried copy-pasting the whole example (from the link above) but readEntity is not a method of Response. I found the following post on this Read response body in JAX-RS client from a post request. But I am using version 2.0 of javax.ws.rs. So, here is a little confusion for me.
public PowerBIController() throws Exception {
client = ClientBuilder.newClient();
service = Executors.newSingleThreadExecutor();
context = new AuthenticationContext(AUTH_URI, VALIDATE_AUTHORITY, service);
String powerBIAccessToken = getToken(RESOURCE_URI, NATIVE_CLIENT_ID, USER_AT_TENANT, PASSWORD);
post(biTarget, powerBIAccessToken);
}
private void post(WebTarget biTarget, String powerBIAccessToken) throws URISyntaxException, IOException, ExecutionException, InterruptedException {
Response response = target
Invocation.Builder builder = biTarget.request(MediaType.APPLICATION_JSON);
Invocation.Builder header = builder.header("Authorization",
"Bearer " + powerBIAccessToken);
response = header.get();
System.out.println("header: " + header.toString());
System.out.println("status: " + response.getStatus());
System.out.println("body:" + response.readEntity(String.class));
}
I've checked at http://docs.powerbi.apiary.io/. Here I have to log in to my Office 365 account and then I can use the same code to get the list of datasets. Here I don't have to authenticate, which could make the difference but when I run as debug I can clearly see I have an accesstoken. Here is the code they say can call the get request properly. Obviously this doesn't work I'm also quite sure the target has typos:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
Client client = ClientBuilder.newClient();
Response response = client.target("https://api.powerbi.com/beta/myorghttps://api.powerbi.com/beta/myorg/datasets{?defaultRetentionPolicy}")
.request(MediaType.TEXT_PLAIN_TYPE)
.header("undefined", "")
.get();
System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
I've tried using Fiddler to see what is actually happening when I run. However, Fiddler is showing no activity at all (even though I checked the https option).
Finally here are my dependencies for this code:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
I'm really looking forward to any help. If anything is wrong with my question please say so. I tried my best to be clear and follow the rules of this forum but I might've missed something.
Much thanks in advance
ANSWER: I was also using azure-media 0.6.0 for parts of my program. This includes a jersey-core 1.3.1. Conclusion: Even though I thought I was importing from javax.ws.rs 2.0 (which it even said if you looked at the type) It was actually getting its object definitions from jersey 1.3.1. This held for more than just the azure-media dependency.
So I will post the dependencies that needed exclusions and the eventual dependencies which were necessary.
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-management</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.7.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-serviceruntime</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-media</artifactId>
<version>0.6.0</version>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
</exclusion>
</exclusions>
</dependency>
The necessary dependencies:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.19</version>
</dependency>
</dependencies>