I am having an issue with the OAuthClientImpl.getInstance() method that is on line 26. It is spitting out this error message:
Exception in thread "main" java.lang.ExceptionInInitializerError
at OAuth.main(OAuth.java:26)
Caused by: java.lang.ClassCastException: org.apache.logging.slf4j.SLF4JLoggerContext cannot be cast to org.apache.logging.log4j.core.LoggerContext
at org.apache.log4j.Logger.getLogger(Logger.java:41)
at com.etrade.etws.oauth.sdk.client.OAuthClientImpl.<init>(OAuthClientImpl.java:22)
at com.etrade.etws.oauth.sdk.client.OAuthClientImpl.<clinit>(OAuthClientImpl.java:24)
... 1 more
It seems to me that the issue is a communication issue between log4j and the E*Trade OAuth jar, although with my limited experience with Java/coding in general I have no idea how to go about fixing this issue, since I couldn't find much helpful information on Google. I decompiled the E*Trade jar and the log4j and found this code:
E*Trade:
public class OAuthClientImpl
implements IOAuthClient
{
private Logger logger = Logger.getLogger(getClass());
private static OAuthClientImpl instance = new OAuthClientImpl();
public static OAuthClientImpl getInstance()
{
return instance;
}
Log4j:
public static Logger getLogger(final Class<?> clazz) {
return (Logger) Category.getInstance((LoggerContext) PrivateManager.getContext(), clazz);
}
Below is my code, it is the E*Trade API sample code with a few minor tweaks.
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.etrade.etws.account.Account;
import com.etrade.etws.account.AccountListResponse;
import com.etrade.etws.account.ETWSException;
import com.etrade.etws.oauth.sdk.client.IOAuthClient;
import com.etrade.etws.oauth.sdk.client.OAuthClientImpl;
import com.etrade.etws.oauth.sdk.common.Token;
import com.etrade.etws.sdk.client.ClientRequest;
import com.etrade.etws.sdk.client.Environment;
public class OAuth
{
public static void main(String[] args) throws IOException, URISyntaxException, com.etrade.etws.sdk.common.ETWSException
{
//Variables
IOAuthClient client = null;
ClientRequest request = null;
Token token = null;
String oauth_consumer_key = null; // Your consumer key
String oauth_consumer_secret = null; // Your consumer secret
String oauth_request_token = null; // Request token
String oauth_request_token_secret = null; // Request token secret
client = OAuthClientImpl.getInstance(); // Instantiate IOAUthClient
request = new ClientRequest(); // Instantiate ClientRequest
request.setEnv(Environment.SANDBOX); // Use sandbox environment
request.setConsumerKey(oauth_consumer_key); //Set consumer key
request.setConsumerSecret(oauth_consumer_secret);
token = client.getRequestToken(request); // Get request-token object
oauth_request_token = token.getToken(); // Get token string
oauth_request_token_secret = token.getSecret(); // Get token secret
}
public void OAuthVerify(IOAuthClient client, ClientRequest request) throws IOException, URISyntaxException, com.etrade.etws.sdk.common.ETWSException
{
String authorizeURL = null;
authorizeURL = client.getAuthorizeUrl(request); // E*TRADE authorization URL
URI uri = new java.net.URI(authorizeURL);
Desktop desktop = Desktop.getDesktop();
desktop.browse(uri);
}
}
Related
I'm not able to find a way to read messages from pub/sub using java.
I'm using this maven dependency in my pom
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>0.17.2-alpha</version>
</dependency>
I implemented this main method to create a new topic:
public static void main(String... args) throws Exception {
// Your Google Cloud Platform project ID
String projectId = ServiceOptions.getDefaultProjectId();
// Your topic ID
String topicId = "my-new-topic-1";
// Create a new topic
TopicName topic = TopicName.create(projectId, topicId);
try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
topicAdminClient.createTopic(topic);
}
}
The above code works well and, indeed, I can see the new topic I created using the google cloud console.
I implemented the following main method to write a message to my topic:
public static void main(String a[]) throws InterruptedException, ExecutionException{
String projectId = ServiceOptions.getDefaultProjectId();
String topicId = "my-new-topic-1";
String payload = "Hellooooo!!!";
PubsubMessage pubsubMessage =
PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(payload)).build();
TopicName topic = TopicName.create(projectId, topicId);
Publisher publisher;
try {
publisher = Publisher.defaultBuilder(
topic)
.build();
publisher.publish(pubsubMessage);
System.out.println("Sent!");
} catch (IOException e) {
System.out.println("Not Sended!");
e.printStackTrace();
}
}
Now I'm not able to verify if this message was really sent.
I would like to implement a message reader using a subscription to my topic.
Could someone show me a correct and working java example about reading messages from a topic?
Anyone can help me?
Thanks in advance!
Here is the version using the google cloud client libraries.
package com.techm.data.client;
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage;
import com.google.pubsub.v1.PushConfig;
/**
* A snippet for Google Cloud Pub/Sub showing how to create a Pub/Sub pull
* subscription and asynchronously pull messages from it.
*/
public class CreateSubscriptionAndConsumeMessages {
private static String projectId = "projectId";
private static String topicId = "topicName";
private static String subscriptionId = "subscriptionName";
public static void createSubscription() throws Exception {
ProjectTopicName topic = ProjectTopicName.of(projectId, topicId);
ProjectSubscriptionName subscription = ProjectSubscriptionName.of(projectId, subscriptionId);
try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
subscriptionAdminClient.createSubscription(subscription, topic, PushConfig.getDefaultInstance(), 0);
}
}
public static void main(String... args) throws Exception {
ProjectSubscriptionName subscription = ProjectSubscriptionName.of(projectId, subscriptionId);
createSubscription();
MessageReceiver receiver = new MessageReceiver() {
#Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
System.out.println("Received message: " + message.getData().toStringUtf8());
consumer.ack();
}
};
Subscriber subscriber = null;
try {
subscriber = Subscriber.newBuilder(subscription, receiver).build();
subscriber.addListener(new Subscriber.Listener() {
#Override
public void failed(Subscriber.State from, Throwable failure) {
// Handle failure. This is called when the Subscriber encountered a fatal error
// and is
// shutting down.
System.err.println(failure);
}
}, MoreExecutors.directExecutor());
subscriber.startAsync().awaitRunning();
// In this example, we will pull messages for one minute (60,000ms) then stop.
// In a real application, this sleep-then-stop is not necessary.
// Simply call stopAsync().awaitTerminated() when the server is shutting down,
// etc.
Thread.sleep(60000);
} finally {
if (subscriber != null) {
subscriber.stopAsync().awaitTerminated();
}
}
}
}
This is working fine for me.
The Cloud Pub/Sub Pull Subscriber Guide has sample code for reading messages from a topic.
I haven't used google cloud client libraries but used the api client libraries. Here is how I created a subscription.
package com.techm.datapipeline.client;
import java.io.IOException;
import java.security.GeneralSecurityException;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.Pubsub.Projects.Subscriptions.Create;
import com.google.api.services.pubsub.Pubsub.Projects.Subscriptions.Get;
import com.google.api.services.pubsub.Pubsub.Projects.Topics;
import com.google.api.services.pubsub.model.ExpirationPolicy;
import com.google.api.services.pubsub.model.Subscription;
import com.google.api.services.pubsub.model.Topic;
import com.techm.datapipeline.factory.PubsubFactory;
public class CreatePullSubscriberClient {
private final static String PROJECT_NAME = "yourProjectId";
private final static String TOPIC_NAME = "yourTopicName";
private final static String SUBSCRIPTION_NAME = "yourSubscriptionName";
public static void main(String[] args) throws IOException, GeneralSecurityException {
Pubsub pubSub = PubsubFactory.getService();
String topicName = String.format("projects/%s/topics/%s", PROJECT_NAME, TOPIC_NAME);
String subscriptionName = String.format("projects/%s/subscriptions/%s", PROJECT_NAME, SUBSCRIPTION_NAME);
Topics.Get listReq = pubSub.projects().topics().get(topicName);
Topic topic = listReq.execute();
if (topic == null) {
System.err.println("Topic doesn't exist...run CreateTopicClient...to create the topic");
System.exit(0);
}
Subscription subscription = null;
try {
Get getReq = pubSub.projects().subscriptions().get(subscriptionName);
subscription = getReq.execute();
} catch (GoogleJsonResponseException e) {
if (e.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
System.out.println("Subscription " + subscriptionName + " does not exist...will create it");
}
}
if (subscription != null) {
System.out.println("Subscription already exists ==> " + subscription.toPrettyString());
System.exit(0);
}
subscription = new Subscription();
subscription.setTopic(topicName);
subscription.setPushConfig(null); // indicating a pull
ExpirationPolicy expirationPolicy = new ExpirationPolicy();
expirationPolicy.setTtl(null); // never expires;
subscription.setExpirationPolicy(expirationPolicy);
subscription.setAckDeadlineSeconds(null); // so defaults to 10 sec
subscription.setRetainAckedMessages(true);
Long _week = 7L * 24 * 60 * 60;
subscription.setMessageRetentionDuration(String.valueOf(_week)+"s");
subscription.setName(subscriptionName);
Create createReq = pubSub.projects().subscriptions().create(subscriptionName, subscription);
Subscription createdSubscription = createReq.execute();
System.out.println("Subscription created ==> " + createdSubscription.toPrettyString());
}
}
And once you create the subscription (pull type)...this is how you pull the messages from the topic.
package com.techm.datapipeline.client;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.util.Base64;
import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.Pubsub.Projects.Subscriptions.Acknowledge;
import com.google.api.services.pubsub.Pubsub.Projects.Subscriptions.Get;
import com.google.api.services.pubsub.Pubsub.Projects.Subscriptions.Pull;
import com.google.api.services.pubsub.model.AcknowledgeRequest;
import com.google.api.services.pubsub.model.Empty;
import com.google.api.services.pubsub.model.PullRequest;
import com.google.api.services.pubsub.model.PullResponse;
import com.google.api.services.pubsub.model.ReceivedMessage;
import com.techm.datapipeline.factory.PubsubFactory;
public class PullSubscriptionsClient {
private final static String PROJECT_NAME = "yourProjectId";
private final static String SUBSCRIPTION_NAME = "yourSubscriptionName";
private final static String SUBSCRIPTION_NYC_NAME = "test";
public static void main(String[] args) throws IOException, GeneralSecurityException {
Pubsub pubSub = PubsubFactory.getService();
String subscriptionName = String.format("projects/%s/subscriptions/%s", PROJECT_NAME, SUBSCRIPTION_NAME);
//String subscriptionName = String.format("projects/%s/subscriptions/%s", PROJECT_NAME, SUBSCRIPTION_NYC_NAME);
try {
Get getReq = pubSub.projects().subscriptions().get(subscriptionName);
getReq.execute();
} catch (GoogleJsonResponseException e) {
if (e.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
System.out.println("Subscription " + subscriptionName
+ " does not exist...run CreatePullSubscriberClient to create");
}
}
PullRequest pullRequest = new PullRequest();
pullRequest.setReturnImmediately(false); // wait until you get a message
pullRequest.setMaxMessages(1000);
Pull pullReq = pubSub.projects().subscriptions().pull(subscriptionName, pullRequest);
PullResponse pullResponse = pullReq.execute();
List<ReceivedMessage> msgs = pullResponse.getReceivedMessages();
List<String> ackIds = new ArrayList<String>();
int i = 0;
if (msgs != null) {
for (ReceivedMessage msg : msgs) {
ackIds.add(msg.getAckId());
//System.out.println(i++ + ":===:" + msg.getAckId());
String object = new String(Base64.decodeBase64(msg.getMessage().getData()));
System.out.println("Decoded object String ==> " + object );
}
//acknowledge all the received messages
AcknowledgeRequest content = new AcknowledgeRequest();
content.setAckIds(ackIds);
Acknowledge ackReq = pubSub.projects().subscriptions().acknowledge(subscriptionName, content);
Empty empty = ackReq.execute();
}
}
}
Note: This client only waits until it receives at least one message and terminates if it's receives one (up to a max of value - set in MaxMessages) at once.
Let me know if this helps. I'm going to try the cloud client libraries soon and will post an update once I get my hands on them.
And here's the missing factory class ...if you plan to run it...
package com.techm.datapipeline.factory;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.PubsubScopes;
public class PubsubFactory {
private static Pubsub instance = null;
private static final Logger logger = Logger.getLogger(PubsubFactory.class.getName());
public static synchronized Pubsub getService() throws IOException, GeneralSecurityException {
if (instance == null) {
instance = buildService();
}
return instance;
}
private static Pubsub buildService() throws IOException, GeneralSecurityException {
logger.log(Level.FINER, "Start of buildService");
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);
// Depending on the environment that provides the default credentials (for
// example: Compute Engine, App Engine), the credentials may require us to
// specify the scopes we need explicitly.
if (credential.createScopedRequired()) {
Collection<String> scopes = new ArrayList<>();
scopes.add(PubsubScopes.PUBSUB);
credential = credential.createScoped(scopes);
}
logger.log(Level.FINER, "End of buildService");
// TODO - Get the application name from outside.
return new Pubsub.Builder(transport, jsonFactory, credential).setApplicationName("Your Application Name/Version")
.build();
}
}
The message reader is injected on the subscriber. This part of the code will handle the messages:
MessageReceiver receiver =
new MessageReceiver() {
#Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
// handle incoming message, then ack/nack the received message
System.out.println("Id : " + message.getMessageId());
System.out.println("Data : " + message.getData().toStringUtf8());
consumer.ack();
}
};
I want to connect Java with JIRA trial account. I tested this code:
public class JiraImpl
{
private static URI JIRA_URL = URI.create("https://sonoratest.atlassian.net");
private static final String JIRA_ADMIN_USERNAME = "sonoratestw#gmail.com";
private static final String JIRA_ADMIN_PASSWORD = "sonpass";
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException
{
try
{
AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
JiraRestClient restClient = factory.createWithBasicHttpAuthentication(JIRA_URL, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD);
Iterable<BasicProject> allProjects = restClient.getProjectClient().getAllProjects().claim();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
But when I run it nothing happens. Wahat is the proper way to get data from JIRA using REST API?
Update. I also tried this:
private static URI JIRA_URL = URI.create("https://sonoratest.atlassian.net/rest/auth/1/session");
I get
java.util.concurrent.ExecutionException: RestClientException{statusCode=Optional.of(404), errorCollections=[ErrorCollection{status=404, errors={}, errorMessages=[]}]}
at com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:299)
at com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:286)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
at com.atlassian.jira.rest.client.internal.async.DelegatingPromise.get(DelegatingPromise.java:102)
at com.jira.impl.JiraImpl.main(JiraImpl.java:23)
Caused by: RestClientException{statusCode=Optional.of(404), errorCollections=[ErrorCollection{status=404, errors={}, errorMessages=[]}]}
Try getting an issue first, since that is so basic.
import java.net.URI;
import java.util.Optional;
import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
import com.atlassian.util.concurrent.Promise;
public class JRC
{
public Issue getIssue(String issueKey) throws Exception
{
final URI jiraServerUri = new URI("https://jira-domain");
final JiraRestClient restClient = new AsynchronousJiraRestClientFactory().createWithBasicHttpAuthentication(jiraServerUri, "user#domain.com", "password");
Promise issuePromise = restClient.getIssueClient().getIssue(issueKey);
return Optional.ofNullable((Issue) issuePromise.claim()).orElseThrow(() -> new Exception("No such issue"));
}
}
You can also take a look at this code to get a fully working sample:
https://github.com/somaiah/jrjc
I have been trying to write some basic code to test out Azure KeyVault. At the moment (as you can see from the console log), I can authenticate but KeyVaultClient just fails with a [Fatal Error] :1:1: Premature end of file.
There seems to be a bit of a lack of real-world examples from Microsoft in relation to the azure-java-sdk, so I admit I have been struggling a bit doing my best interpreting the JavaDocs !
16:12:02.391 [main] DEBUG com.example.cli.Main - Launched !
16:12:02.453 [main] DEBUG e.s.cli.AzureAuthenticationResult -
Authresult getToken
16:12:02.491 [pool-1-thread-1] DEBUG
c.m.aad.adal4j.AuthenticationContext - [Correlation ID:
XXXXXXX-XXX-XXX-XXX-XXXXXXX] Using Client Http Headers:
x-client-SKU=java;x-client-VER=1.0.0;x-client-OS=XXXX;x-client-CPU=XXXX;return-client-request-id=true;client-request-id=XXXXXXX-XXX-XXX-XXX-XXXXXXX;
16:12:02.491 [pool-1-thread-1] INFO
c.m.a.adal4j.AuthenticationAuthority - [Correlation ID:
XXXXXXX-XXX-XXX-XXX-XXXXXXX] Instance discovery was successful
16:12:05.142 [pool-1-thread-1] DEBUG
c.m.aad.adal4j.AuthenticationContext - [Correlation ID:
XXXXXXX-XXX-XXX-XXX-XXXXXXX] Access Token with hash
'ZZZZZZZZZZZZZZZZZZZZZZZZ' returned
[Fatal Error] :1:1: Premature end
of file.
16:12:08.135 [main] ERROR com.example.cli.Main - null
java.util.concurrent.ExecutionException:
com.microsoft.windowsazure.exception.ServiceException:
at
java.util.concurrent.FutureTask.report(FutureTask.java:122)
~[na:1.8.0_45]
at
java.util.concurrent.FutureTask.get(FutureTask.java:192)
~[na:1.8.0_45]
at
com.microsoft.azure.keyvault.FutureAdapter.get(FutureAdapter.java:53)
~[azure-keyvault-0.9.0.jar:na]
at
com.example.cli.Main.main(Main.java:37) ~[classes/:na]
at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
~[na:1.8.0_45]
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_45]
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Method.java:497)
~[na:1.8.0_45]
at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
[idea_rt.jar:na]
Caused by:
com.microsoft.windowsazure.exception.ServiceException:
at >com.microsoft.windowsazure.exception.ServiceException.createFromXml(ServiceException.java:216)
~[azure-core-0.9.0.jar:na]
at
com.microsoft.azure.keyvault.KeyOperationsImpl.sign(KeyOperationsImpl.java:1524)
~[azure-keyvault-0.9.0.jar:na]
at
com.microsoft.azure.keyvault.KeyOperationsImpl$13.call(KeyOperationsImpl.java:1447)
~[azure-keyvault-0.9.0.jar:na]
at >com.microsoft.azure.keyvault.KeyOperationsImpl$13.call(KeyOperationsImpl.java:1444)
~[azure-keyvault-0.9.0.jar:na]
at
java.util.concurrent.FutureTask.run(FutureTask.java:266)
~[na:1.8.0_45]
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
~[na:1.8.0_45]
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
~[na:1.8.0_45]
at java.lang.Thread.run(Thread.java:745)
~[na:1.8.0_45]
Process finished with exit code 0
package com.example.cli;
import com.microsoft.azure.keyvault.KeyVaultClient;
import com.microsoft.azure.keyvault.KeyVaultClientService;
import com.microsoft.azure.keyvault.models.KeyOperationResult;
import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm;
import com.microsoft.windowsazure.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.*;
import java.util.Random;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Main.class);
logger.debug("Launched !");
try {
byte[] plainText = new byte[100];
new Random(0x1234567L).nextBytes(plainText);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(plainText);
byte[] digest = md.digest();
Configuration configuration = AzureKVCredentials.createConfiguration();
KeyVaultClient keyVaultClient = KeyVaultClientService.create(configuration);
Future<KeyOperationResult> keyOperationPromise;
KeyOperationResult keyOperationResult;
keyOperationPromise = keyVaultClient.signAsync("https://XXXXXXX.vault.azure.net/keys/XXXXXXX/XXXXXXX”,JsonWebKeySignatureAlgorithm.RS256,digest);
keyOperationResult = keyOperationPromise.get(); // <=== THIS IS LINE 37 IN THE STACKTRACE ;-) <====
byte[] res = keyOperationResult.getResult();
String b64 = java.util.Base64.getEncoder().encodeToString(res);
logger.debug(b64);
} catch (Exception e) {
logger.error(null,e);
}
}
}
For using Azure KeyVault, you can try to use Azure REST APIs to manage and operate the Key Vault. Please refer to the Key Vault REST document https://msdn.microsoft.com/en-us/library/azure/dn903630.aspx.
There are two set of APIs for Key Vault management and Keys & Secrets operations that need different access tokens from different resource uri.
For management apis, the resource uri is https://management.core.windows.net/.
For operation apis, the resource uri is https://vault.azure.net. (Note: Please notice there is no symbol / at the end of the uri. )
Here is a sample code as references.
package aad.keyvault;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.naming.ServiceUnavailableException;
import javax.net.ssl.HttpsURLConnection;
import org.apache.commons.io.IOUtils;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
public class RestAPISample {
private static final String subscriptionId = "<subscription_id>";
private static final String resourceGroupName = "<resource_group_name>";
private static final String vaultName = "<vault_name>";
private static final String apiVersion = "2015-06-01";
private static final String getKeyVaultInfoUri = String.format(
"https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.KeyVault/vaults/%s?api-version=%s",
subscriptionId, resourceGroupName, vaultName, apiVersion);
private static final String tenantId = "<tenant_id>";
private static final String authority = String.format("https://login.windows.net/%s", tenantId);
private static final String clientId = "<client_id>";
private static final String clientSecret = "<client_secret_key>";
private static final String keyName = "<keyvault_key>";
private static final String getInfoFromAKeyUri = String.format("https://%s.vault.azure.net/keys/%s?api-version=%s",
vaultName, keyName, apiVersion);
public static String getAccessToken(String resource)
throws MalformedURLException, InterruptedException, ExecutionException, ServiceUnavailableException {
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(authority, true, service);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
Future<AuthenticationResult> future = context.acquireToken(resource, credential, null);
result = future.get();
} finally {
service.shutdown();
}
String accessToken = null;
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
} else {
accessToken = result.getAccessToken();
System.out.println("Access Token: " + accessToken);
}
return accessToken;
}
public static void getKeyVaultInfo() throws MalformedURLException, IOException, ServiceUnavailableException,
InterruptedException, ExecutionException {
System.out.println(getKeyVaultInfoUri);
HttpsURLConnection conn = (HttpsURLConnection) new URL(getKeyVaultInfoUri).openConnection();
conn.setRequestProperty("Authorization", "Bearer " + getAccessToken("https://management.core.windows.net/"));
conn.addRequestProperty("Content-Type", "application/json");
String resp = IOUtils.toString(conn.getInputStream());
System.out.println(resp);
}
public static void getKeyInfo() throws MalformedURLException, IOException, ServiceUnavailableException, InterruptedException, ExecutionException {
System.out.println(getInfoFromAKeyUri);
HttpsURLConnection conn = (HttpsURLConnection) new URL(getInfoFromAKeyUri).openConnection();
conn.setRequestProperty("Authorization", "Bearer " + getAccessToken("https://vault.azure.net"));
conn.addRequestProperty("Content-Type", "application/json");
String resp = IOUtils.toString(conn.getInputStream());
System.out.println(resp);
}
public static void main(String[] args)
throws InterruptedException, ExecutionException, ServiceUnavailableException, IOException {
getKeyVaultInfo();
getKeyInfo();
}
}
Azure Key Vault operation APIs need different permissions setted by using command set-policy. For example Get information about a key(https://msdn.microsoft.com/en-us/library/azure/dn878080.aspx), it need authorization requires the keys/get permission by using Azure CLI cmd azure keyvault set-policy --vault-name <vault-name> --spn <service-principal-no.> --perms-to-keys '["get"]' to add permission get to keys.
Your code works for me, so I suspect your credentials object (which you didn't provide) is not valid. In special, make sure you use a KeyVaultConfiguration instance.
Here's my working version of your AzureKVCredentials:
package com.example.cli;
import java.util.*;
import java.util.concurrent.*;
import com.microsoft.aad.adal4j.*;
import org.apache.http.*;
import org.apache.http.message.*;
import com.microsoft.azure.keyvault.*;
import com.microsoft.azure.keyvault.authentication.*;
import com.microsoft.windowsazure.*;
import com.microsoft.windowsazure.core.pipeline.filter.*;
public class AzureKVCredentials extends KeyVaultCredentials {
public static Configuration createConfiguration() {
return KeyVaultConfiguration.configure(null, new AzureKVCredentials());
}
#Override
public Header doAuthenticate(ServiceRequestContext request, Map<String, String> challenge) {
try {
String authorization = challenge.get("authorization");
String resource = challenge.get("resource");
AuthenticationResult authResult = getAccessToken(authorization, resource);
return new BasicHeader("Authorization", authResult.getAccessTokenType() + " " + authResult.getAccessToken());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception {
String clientId = "<app id of your Azure application>";
String clientKey = "<application key>";
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
AuthenticationContext context = new AuthenticationContext(authorization, false, service);
Future<AuthenticationResult> future = null;
ClientCredential credentials = new ClientCredential(clientId, clientKey);
future = context.acquireToken(resource, credentials, null);
result = future.get();
} finally {
service.shutdown();
}
if (result == null) {
throw new RuntimeException("authentication result was null");
}
return result;
}
}
This code is based on these sources from the azure-sdk-for-java.
Ok, the case is simple. I need to be able to enable/disable logging for a JDK class (HttpURLConnection) programmatically.
public class HttpLoggingTest {
/**
Just a dummy to get some action from HttpURLConnection
*/
private static void getSomething(String urlStr) throws MalformedURLException, IOException {
System.out.println("----- " + urlStr);
HttpURLConnection conn = (HttpURLConnection) new URL("http://www.google.com").openConnection();
for (Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
conn.disconnect();
}
public static void main(String[] args) throws MalformedURLException, IOException {
// HERE : Enable JDK logging for class
// sun.net.www.protocol.http.HttpURLConnection
getSomething("http://www.goodle.com");
// HERE: Disable JDK logging for class
// sun.net.www.protocol.http.HttpURLConnection
getSomething("http://www.microsoft.com");
}
}
In other words: before the first URL call the logging must be enabled and then disabled before the next call.
That is the challenge !
I'm unable to figure out how to do it.
Must work with Java 7.
Note:
I can do it by using configuration file, logging.properties :
sun.net.www.protocol.http.HttpURLConnection.level = ALL
but I want to have a programmatic solution.
UPDATE
Here's code that works in Java 6 but not in Java 7:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map.Entry;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HttpLoggingTest {
/**
Just a dummy to get some action from HttpURLConnection
*/
private static void getSomething(String urlStr) throws MalformedURLException, IOException {
System.out.println("----- " + urlStr);
HttpURLConnection conn = (HttpURLConnection) new URL("http://www.google.com").openConnection();
for (Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
conn.disconnect();
}
private static void enableConsoleHandler() {
//get the top Logger
Logger topLogger = java.util.logging.Logger.getLogger("");
// Handler for console (reuse it if it already exists)
Handler consoleHandler = null;
//see if there is already a console handler
for (Handler handler : topLogger.getHandlers()) {
if (handler instanceof ConsoleHandler) {
//found the console handler
consoleHandler = handler;
break;
}
}
if (consoleHandler == null) {
//there was no console handler found, create a new one
consoleHandler = new ConsoleHandler();
topLogger.addHandler(consoleHandler);
}
consoleHandler.setLevel(Level.ALL);
}
public static void main(String[] args) throws MalformedURLException, IOException {
enableConsoleHandler();
final Logger httpLogger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
// Enable JDK logging for class
//sun.net.www.protocol.http.HttpURLConnection
httpLogger.setLevel(java.util.logging.Level.FINE);
getSomething("http://www.goodle.com");
// Disable JDK logging for class
// sun.net.www.protocol.http.HttpURLConnection
httpLogger.setLevel(java.util.logging.Level.INFO);
getSomething("http://www.microsoft.com");
}
}
UPDATE2
In order to make sure that a solution only enables output from our target class (and not all sorts of other JDK internal classes) I've created this minimal JAXB example. Here JAXB is simply an example of 'something else', it could have been any other part of the JDK that also use PlatformLogger.
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Minimal dummy JAXB example. Only purpose is to provoke
* some JAXB action. Non-prod quality!
*/
#XmlRootElement(name = "book")
public class Celebrity {
#XmlElement
public String getFirstName() {
return "Marilyn";
}
#XmlElement
public String getLastName() {
return "Monroe";
}
public void printXML() {
JAXBContext context;
try {
context = JAXBContext.newInstance(Celebrity.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(this, System.out);
} catch (JAXBException ex) {
}
}
}
Instantiate an instance of the Celebrity class and call printXML(). Put that into getSomething() method. This must not generate JAXB internal logging output ... or else you've enabled logging for more than you thought.
Stumbled over PlatformLoggingMXBean the other day. I'll need to try something like:
PlatformLoggingMXBean platformLoggingMXBean =
ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class);
platformLoggingMXBean.setLoggerLevel(
"sun.net.www.protocol.http.HttpURLConnection", "FINE");
and see it it works.
Try:
java.util.logging.Logger logger =
java.util.logging.Logger.getLogger(
"sun.net.www.protocol.http.HttpURLConnection");
logger.setLevel(java.util.logging.Level.FINE);
I am running the YouTubeSample given on the google developers website. I have no errors in the code and my imports appear to be fine. But when I run the project I get the aforementioned error.
I have done some searches but to be honest I have been unable to work out what the problem is. I have already tried importing an external jar guava but it didn't help.
Any help is appreciated. Here is the full class
package com.pengilleys.googlesamples;
import java.io.IOException;
import java.util.List;
import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.googleapis.json.JsonCParser;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.Key;
public class YouTubeSample {
public static class VideoFeed {
#Key List<Video> items;
}
public static class Video {
#Key String title;
#Key String description;
#Key Player player;
}
public static class Player {
#Key("default") String defaultUrl;
}
public static class YouTubeUrl extends GenericUrl {
#Key final String alt = "jsonc";
#Key String author;
#Key("max-results") Integer maxResults;
YouTubeUrl(String url) {
super(url);
}
}
public static void main(String[] args) throws IOException {
// set up the HTTP request factory
HttpTransport transport = new NetHttpTransport();
final JsonFactory jsonFactory = new JacksonFactory();
HttpRequestFactory factory = transport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) {
// set the parser
JsonCParser parser = new JsonCParser();
parser.jsonFactory = jsonFactory;
request.addParser(parser);
// set up the Google headers
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("Google-YouTubeSample/1.0");
headers.gdataVersion = "2";
request.headers = headers;
}
});
// build the YouTube URL
YouTubeUrl url = new YouTubeUrl("https://gdata.youtube.com/feeds/api/videos");
url.author = "searchstories";
url.maxResults = 2;
// build the HTTP GET request
HttpRequest request = factory.buildGetRequest(url);
// execute the request and the parse video feed
VideoFeed feed = request.execute().parseAs(VideoFeed.class);
for (Video video : feed.items) {
System.out.println();
System.out.println("Video title: " + video.title);
System.out.println("Description: " + video.description);
System.out.println("Play URL: " + video.player.defaultUrl);
}
}
}
The setup documentation gives a list of dependencies:
Depending on the application you are building, you may also need these dependencies:
Apache HTTP Client version 4.0.3
Google Guava version r09
Jackson version 1.6.7
Google GSON version 1.6
In this case, it looks like it's Guava which is missing. I don't know what you mean about "exporting" Guava, but if you include the Guava r09 jar file in the classpath when you're running the code, it should be fine.
what's the extra ); for above the // build the YouTube URL and did you mean to close main on that line?