Java Service Bus Shared Access Token - java

Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
URL,
"RootManageSharedAccessKey",
token,
".servicebus.windows.net"
);
This is the code for configuration for java service bus implementation. I am interested in passing a shared access signature not a shared access key. I am not sure if this implementation for the java azure sdk supports this. How exactly would I do this. I keep getting a 401-unauthorized error when I use the shared access signature token in the token variable. Any ideas?

According to the source code of Azure Service Bus SDK for Java, the four arguments for the function configureWithSASAuthentication should be the namespace, sasKeyName, sasKey & serviceBusRootUri(default pass ".servicebus.windows.net").
The namespace, sasKeyName & sasKey you can find them via click the CONNECTION INFORMATION button at the bottom of your service bus, please see the figures below.
Fig 1. The CONNECTION INFORMATION button at the bottom of the service bus page
Fig 2. Copy the CONNECTION STRING and extract the namespace, sasKeyName & sasKey
For example, the connection string is Endpoint=sb://abc-ns.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=ABCdefg123!##=, then the namespace, sasKeyName, sasKey are separately abc-ns, RootManageSharedAccessKey, ABCdefg123!##=.
So the code should be as below.
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"abc-ns",
"RootManageSharedAccessKey",
"ABCdefg123!##=",
".servicebus.windows.net"
);
And you can also find them at the CONFIGURE tab of your service bus page, please see the figure below.
Fig 3. The CONFIGURE tab

I can see that you created a Configuration object here. Normally we use it to creat a topic in Java, eg:
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"namespace",
"sasKeyName",
"sasKey",
"serviceBusRootUri"
);
ServiceBusContract service = ServiceBusService.create(config);
TopicInfo topicInfo = new TopicInfo("TestTopic");
CreateTopicResult result = service.createTopic(topicInfo);
or to create a queue, eg:
Configuration config =
ServiceBusConfiguration.configureWithSASAuthentication(
"namespace",
"sasKeyName",
"sasKey",
"serviceBusRootUri"
);
ServiceBusContract service = ServiceBusService.create(config);
QueueInfo queueInfo = new QueueInfo("TestQueue");
CreateQueueResult result = service.createQueue(queueInfo);
and also we can create them by shared access signature:
create a topic(c#)
Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", "namespace", string.Empty);
string name = "sasKeyName";
string key = "sasKey";
TokenProvider tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(name, key);
NamespaceManager namespaceManager = new NamespaceManager(uri, tokenProvider);
namespaceManager.CreateTopic("DataCollectionTopic");
create a queue(c#):
Uri uri = ServiceBusEnvironment.CreateServiceUri("sb",
"namespace", string.Empty);
string name = "sasKeyName";
string key = "sasKey";
TokenProvider tokenProvider =
TokenProvider.CreateSharedAccessSignatureTokenProvider(name, key);
NamespaceManager namespaceManager =
new NamespaceManager(uri, tokenProvider);
namespaceManager.CreateQueue("DataCollectionQueue");
The namespace, sasKeyName, sasKey are configured in portal just as what Perter showed.

Related

In java with azure function #ServiceBusQueueTrigger, how to get the Label, Custom Properties and Broker Properties?

This is the azure web page example in JAVA to get the message content from the azure service bus :
#FunctionName("sbprocessor")
public void serviceBusProcess(
#ServiceBusQueueTrigger(name = "msg",
queueName = "myqueuename",
connection = "myconnvarname") String message,
final ExecutionContext context
) {
context.getLogger().info(message);
}
This only return the content of the message. How is it possible to get the other fields that you can see in Service bus explorer : Label, Custom Properties and Broker Properties ?
You can retrieve message metadata by adding #BindingName("UserProperties") etc. annotation to method parameters like below for example. You can bind to any metadata of a message using binding expression. In this case below, it's "Properties" and "Label".
#FunctionName("sbprocessor")
public void serviceBusProcess(
#ServiceBusQueueTrigger(name = "msg", queueName = "myqueuename", connection = "myconnvarname")
String message,
final ExecutionContext context,
#BindingName("UserProperties")
Map<String, Object> properties,
#BindingName("Label")
String label) {
context.getLogger().info("Message received: " + message + " , properties: " + properties + " , label: " + label);
}
I used Service Bus Explorer as Message Sender to set metadata of the message as below and was able to see those in the consumer side using above code in "UserProperties" binding.
N.B. C# function SDK has a benefit here over Java. In C#, you can get the whole BrokeredMessage object which is easier to navigate for metadata directly. But unfortunately, that's not possible in Java SDK as of now where you have to bind separately.

How to explicitly point my service account file in code

In other Google Services such as Storage, BigQuery you can define what service account you are going to use in the JAVA code:
// You can specify a credential file by providing a path to GoogleCredentials.
// Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
Using Google Secret Manager it seems not possibile. Why?
The only way is to set an environment variable on VM?
I tried as suggested to use Credentials Provider
GoogleCredentials credentials = ServiceAccountCredentials.fromStream(credentialsInputStream);
CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(credentials);
SecretManagerServiceSettings settings = SecretManagerServiceSettings.newBuilder().setCredentialsProvider(credentialsProvider).build();
client = SecretManagerServiceClient.create(settings);
but it doesn't work
Caused by: java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V
at io.grpc.Metadata$Key.validateName(Metadata.java:742)
at io.grpc.Metadata$Key.<init>(Metadata.java:750)
at io.grpc.Metadata$Key.<init>(Metadata.java:668)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:959)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:954)
at io.grpc.Metadata$Key.of(Metadata.java:705)
at io.grpc.Metadata$Key.of(Metadata.java:701)
at com.google.api.gax.grpc.GrpcHeaderInterceptor.<init>(GrpcHeaderInterceptor.java:60)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:239)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.access$1600(InstantiatingGrpcChannelProvider.java:71)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider$1.createSingleChannel(InstantiatingGrpcChannelProvider.java:210)
at com.google.api.gax.grpc.ChannelPool.create(ChannelPool.java:72)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:217)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:200)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:156)
at com.google.cloud.secretmanager.v1.stub.GrpcSecretManagerServiceStub.create(GrpcSecretManagerServiceStub.java:237)
at com.google.cloud.secretmanager.v1.stub.SecretManagerServiceStubSettings.createStub(SecretManagerServiceStubSettings.java:226)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.<init>(SecretManagerServiceClient.java:154)
at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.create(SecretManagerServiceClient.java:135)
because of an Exception in the class com.google.cloud.secretmanager.v1.SecretManagerServiceClient
/**
* Constructs an instance of SecretManagerServiceClient, using the given settings. This is
* protected so that it is easy to make a subclass, but otherwise, the static factory methods
* should be preferred.
*/
protected SecretManagerServiceClient(SecretManagerServiceSettings settings) throws IOException {
this.settings = settings;
this.stub = ((SecretManagerServiceStubSettings) settings.getStubSettings()).createStub();
}
To customize credentials, you can create a custom secretManagerServiceSettings:
SecretManagerServiceSettings secretManagerServiceSettings =
SecretManagerServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
.build();
SecretManagerServiceClient client =
SecretManagerServiceClient.create(secretManagerServiceSettings);

azure java sdk authentication

I would like to list available IP VM's in the new Azure portal using Java SDK.
Couple of years back in the good old classic portal, I had followed the usual management certificate procedure to access vm's,create vm's and work with Azure Endpoints.
Fast fwd now I see that they have used a new portal and new mechanisms to interact with Java SDK. I read somewhere in the above link that with the old way with certificates, I can manage only the class portal resources.
I'm trying to code a simple program which authenticates and lists the vm's of the new portal as a start. Seems like they have complicated it a lot.
I followed the below link to "Create service principal with password"
https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
Then I went to this link
https://azure.microsoft.com/en-us/documentation/samples/resources-java-manage-resource-group/
which asked me go the "See how to create an Auth file" link in above page
(mine is not a webapp and when I try to create the AD as a native client application, it is not allowing me to save keys in configure tab, so I had to create a web app)
After doing all this, I got stuck with this below error
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
'authority' Uri should have at least one segment in the path (i.e.https://<host>/<path>/...)
java.lang.IllegalArgumentException: 'authority' Uri should have at least one segment in the path (i.e. https://<host>/<path>/...)
at com.microsoft.aad.adal4j.AuthenticationAuthority.detectAuthorityType(AuthenticationAuthority.java:190)
at com.microsoft.aad.adal4j.AuthenticationAuthority.<init>(AuthenticationAuthority.java:73)
When I checked it says that the error is because I don't have a valid client application id in your Azure Active Directory.
Is there any simple way to authenticate and start using the API's?
#Vikram, I suggest that you can try to refer to the article to create an application on AAD.
Then you can follow the code below to get the access token for authentication.
// The parameters include clientId, clientSecret, tenantId, subscriptionId and resourceGroupName.
private static final String clientId = "<client-id>";
private static final String clientSecret = "<key>";
private static final String tenantId = "<tenant-id>";
private static final String subscriptionId = "<subscription-id>";
// The function for getting the access token via Class AuthenticationResult
private static AuthenticationResult getAccessTokenFromServicePrincipalCredentials()
throws ServiceUnavailableException, MalformedURLException, ExecutionException, InterruptedException {
AuthenticationContext context;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
// TODO: add your tenant id
context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId, false, service);
// TODO: add your client id and client secret
ClientCredential cred = new ClientCredential(clientId, clientSecret);
Future<AuthenticationResult> future = context.acquireToken("https://management.azure.com/", cred, null);
result = future.get();
} finally {
service.shutdown();
}
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
return result;
}
String accessToken = getAccessTokenFromServicePrincipalCredentials().getAccessToken();
If you want to list the VMs on new portal, you can try to use the REST API List the resources in a subscription to get all resources and filter the VMs via the resource type Microsoft.Compute/virtualMachines.
Hope it helps.

Tapestry5 : URL Re-writing : Pass parameters to transformPageRenderLink method

I am upgrading tapestry from 5.2.4 to 5.3.8 and am stuck at re-implementing the URL re-writing part.
In my application a user account can have multiple data stores. User can have same page of different stores active at the same time. Hence I need to put the storeId in page links and event links URLs. So What is done is as follows.
I register MyLinkTransformerClass in AppModule as follows.
#Contribute(PageRenderLinkTransformer.class)
#Primary
public static void provideURLRewriting( OrderedConfiguration<PageRenderLinkTransformer> configuration){
configuration.addInstance(
"Faces", MyLinkTransformer.class);
}
Following is the MyLinkTransformer class which implements PageRenderLinkTransformer
public PageRenderRequestParameters decodePageRenderRequest(
Request request) {
// for incoming requests - remove the store id from URL and
// save into Request as an attribute
String path = request.getPath();
if (path.equals("/")) {
// Redirect to accounts page
return new PageRenderRequestParameters("account", new EmptyEventContext(), false);
}
else {
String start = path.split("/")[1];
if (!ignoredRewriteSet.contains(start) && !start.startsWith("account")) {
String storePath = path.substring(1).substring(path.indexOf("/"));
int idx = storePath.indexOf("/");
if (idx < 0) idx = storePath.length();
String storeId = storePath.substring(0, idx).trim();
RequestHelper.setStoreId(request, storeId);
EventContext urlEventContext = new URLEventContext(contextValueEncoder, new String[]{storeId});
EventContext arrayEventContext = new ArrayEventContext(typeCoercer, "foo");
return new PageRenderRequestParameters(storePath.substring(idx), arrayEventContext, false);
//return new PageRenderRequestParameters(storePath.substring(idx), new EmptyEventContext(), false);
}
}
return null;
}
public Link transformPageRenderLink(
Link defaultLink,
PageRenderRequestParameters parameters) {
// for outgoing requests- This is where I want to access the store Id
// which is stored in Request class of Tapestry as an attribute and
// add it to the URL
return null;
}
So, the idea is to remove storeId from URL in decodePageRenderRequest method and save it in the Request class of Tapestry as an attribute. And while creating outgoing URLs of page link and event link, I want to access the storeId which was saved in Request and inject it to the URL which will be rendered in method transformPageRenderLink.
But I don't know how to pass parameters to transformPageRenderLink method or access Request instance there.
I am following http://blog.tapestry5.de/index.php/2010/09/06/new-url-rewriting-api/ example.
I am new to URL Rewriting, any help with this will be appreciated.
You will probably be interested in the ModeComponentEventLinkEncoder here. It removes a "mode" from the URL and puts it onto the Environment before passing it on to the normal tapestry URL processing.
It's a two way process so the "mode" is included in any links generated on the page.
Note: This is applied as a decorator here

what is accessTokenValue, tokenSecretValue in linkedin-j?

I try to connect with linkedin using linkedin-j api.
we get consumerKeyValue, consumerSecretValue when we register in for application in linked in how to get ccessTokenValue, tokenSecretValue.
following are two lines where we user ccessTokenValue, tokenSecretValue.
final LinkedInApiClientFactory factory = LinkedInApiClientFactory.newInstance(consumerKeyValue, consumerSecretValue);
final LinkedInApiClient client = factory.createLinkedInApiClient(accessTokenValue, tokenSecretValue);

Categories