How to get ip public AWS in Cloudify - cloudify

Using in my script file .sh:
ctx logger info $(ctx instance host_ip)
I get the private IP of my instance on AWS. How do I get the public IP?

Short answer is that as of right now you cannot, but the feature is planned.
More complete answer -
ctx.instance.host_ip maps to a compute node instance's runtime property ctx.instance.runtime_properties[ip]. By convention this is a private ip address.
This property is set if the current node is of, or is derived from, the type cloudify.nodes.Compute, or if the current node has a relationship of, or is derived from, the type cloudify.relationships.contained_in that has a target of node type, or derived from, cloudify.nodes.Compute.
AWS plugin sets the runtime property on node type cloudify.aws.nodes.Instance ctx.instance.runtime_properties['public_ip_address'].
In the meantime, the best solution is to us a script in a lifecycle operation to set a runtime property on the needed node that need's the public IP such as you will find here.

You can get public IP address in the following way:
public_address=$(ctx instance public_ip_address)
ctx logger info "Public IP address is ${public_address}"

Related

Is there a way to map users to individual graphs in Gremlin server?

I am setting up multiple graph mappings to an OrientDB database in Gremlin server. However, I can't find what to script in Groovy plus what to configure in the configuration yaml file in order to be able to map each authenticated user to a single graph, rather than have all the users validated by the authenticator be able to access everything. Is there any way to achieve this?
Gremlin Server does not provide any features for authorization - only authentication. You would have to build something yourself to handle restricting users to different graphs (or other constraints). That would mean building two things:
A custom ChannelInboundHandlerAdapter to handle authorization - maybe called AuthorizationHandler
A custom Channelizer implementation to wire in your custom authorizer to the pipeline - maybe called AuthorizingChannelizer
The AuthorizationHandler would basically just override Netty's channelRead() method
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof RequestMessage){
RequestMessage requestMessage = (RequestMessage) msg;
// examine contents of RequestMessage to see what is being requested
// e.g. the graph - the user information will be there too but
// depending on the authentication method you're using you might need
// to re-decode it at this time as it doesn't appear that the authenticated
// user is placed on the ChannelHandlerContext for some reason. i made
// a note to change that as it seems helpful and is a simple enough thing
// to do
}
}
For the AuthorizingChannelizer you would basically extend the WebSocketChannelizer and override the configure() method:
#Override
public void configure(ChannelPipeline pipeline) {
super.configure(pipeline);
// add an instance of your `AuthorizingChannelizer` to the end of the
// netty pipeline which will put it after the `AuthenticationHandler`
// but before all the Gremlin processing/execution
pipeline.addLast("authorizier", authorizingChannelizer);
}
Then, in your Gremlin Server config you replace the channelizer setting with the fully qualified name of your AuthorizingChannelizer. Assuming you've placed your jar containing that class in Gremlin Server's path it should create an instance of it at startup.
I would look at the existing "handler" and "channelizer" code for more inspiration on how to make this happen.

How to get current user from IHubContext in SignalR?

Suppose in some class library I have access to a specific HubContext:
IHubContext ctx = connectionManager.GetHubContext<MyAwesomeHub>();
How do I get access to the current authenticated .User property?
You can't. The GetHubContext method is normally used for sending messages from a background thread to a client (or many/all clients) so by definition won't have a SignalR user backing it.

Spring Social Facebook

I am developing with Spring Social and Thymeleaf from the quick start example, but I realised that it only supports one Facebook object per controller. This means the sample can't provide support for multiple users and I am guessing it has to do with the #Scope of the variable. Its runs in a Spring boot container and I wonder how I can configure this so that each session has its own Facebook object.
As you suggested, the Facebook object should be configured with request scope. If you're using the configuration support and/or Spring Boot, then it will be request scoped. Therefore, even though the controller is injected once with a Facebook instance, that instance is really a proxy that will delegate to a real FacebookTemplate instance that is created at request time for the authenticated user.
I can only assume that you're referring to the getting started guide example at http://spring.io/guides/gs/accessing-facebook/. In that case, it's using the most simple Spring Boot autoconfiguration possible for Spring Social, which includes a basic (yet not intended for production) implementation of UserIdSource which always returns "anonymous" as the user ID. Therefore, after you create the first Facebook connection, the second browser tries to find a connection for "anonymous", finds it, and gives you an authorized Facebook object.
This may seem peculiar, but it is an example app intended to get you started...and it does that. All you need to do to get a real UserIdSource is to add Spring Security to the project. That will tell Spring Social autoconfiguration to configure a UserIdSource that fetches the current user ID from the security context. This reflects a more real-world use of Spring Social, albeit obviously more involved and beyond the scope of the getting started guide.
But you can look at https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase-boot for a more complete example of Spring Social within Spring Boot.
Spring Boot autoconfigures a lot of things behind the scenes. It does autoconfigure the Facebook, LinkedIn and Twitter properties and sets up the connection factories for social providers.
However, the implementation of UserIdSource always returns “anonymous” as the user ID. Once the first Facebook connection is established the second browser will try to find a connection for “anonymous” which it finds and gives you an authorised Facebook object.
#Configuration
#EnableSocial
#ConditionalOnWebApplication
#ConditionalOnMissingClass("org.springframework.security.core.context.SecurityContextHolder")
protected static class AnonymousUserIdSourceConfig extends SocialConfigurerAdapter {
#Override
public UserIdSource getUserIdSource() {
return new UserIdSource() {
#Override
public String getUserId() {
return "anonymous";
}
};
}
}
Solution
The solution is to override the “anonymous” as the UserId for each new user/session. So for each session, we can simply return a SessionID, however, it may not be unique enough to identify users, especially if it’s being cached or stored somewhere in a connection database.
#Override
public String getUserId() {
RequestAttributes request = RequestContextHolder.currentRequestAttributes();
String uuid = (String) request.getAttribute("_socialUserUUID", RequestAttributes.SCOPE_SESSION);
if (uuid == null) {
uuid = UUID.randomUUID().toString();
request.setAttribute("_socialUserUUID", uuid, RequestAttributes.SCOPE_SESSION);
}
return uuid;
}
The solution for above problem has been talked about in detail over here

Change certain resource strings with robolectric

I have a working robolectric and want to test a component of my application that does HTTP request. Since I don't want these requests to go to my live server but instead to a local test server I want to override a string resources (that contains the servers hostname) during testing.
However, I'm not capable of finding anything in the robolectric documentation that goes remotely in the direction I want :(
I've faced a similar issue in Robolectric 3; you can override a resource at application level using Mockito partial mocks.
First, you tell Robolectric to used a partially mocked Application and to return that when the application context is used: (thanks to this answer: https://stackoverflow.com/a/31386831/327648)
RuntimeEnvironment.application = spy(RuntimeEnvironment.application);
when(RuntimeEnvironment.application.getApplicationContext())
.thenReturn(RuntimeEnvironment.application);
Then you partially mock the Resources object:
Resources spiedResources = spy(app.getResources());
when(app.getResources())
.thenReturn(spiedResources);
Then you can do the real override:
when(spiedResources.getString(R.string.server_address))
.thenReturn("local server address");
I hope this helps.
You can use the technique mentioned at http://robolectric.blogspot.com/2013/04/the-test-lifecycle-in-20.html
This will allow you to override getResources() and use spying to return a hardcoded String or (by default) the String loaded from res/values:
#Override
public Resources getResources() {
Resources resources = spy(super.getResources());
when(resources.getString(R.string.server_address)).thenReturn("local test server address");
return resources;
}

Finding JNP port in JBoss from Servlet

I have a servlet running in JBoss (4.2.2.GA and 4.3-eap) that needs to connect to an EJB to do work.
In general this code works fine to get the Context to connect and make RMI calls (all in the same server).
public class ContextFactory
{
public static final int DEFAULT_JNDI_PORT = 1099;
public static final String DEFAULT_CONTEXT_FACTORY_CLASS = "org.jnp.interfaces.NamingContextFactory";
public static final String DEFAULT_URL_PREFIXES = "org.jboss.naming:org.jnp.interfaces";
public Context createContext(String serverAddress)
{
//combine provider name and port
String providerUrl = serverAddress + ":" + DEFAULT_JNDI_PORT;
//Set properties needed for Context: factory, provider, and package prefixes.
Hashtable<String, String> env = new Hashtable<String, String>(3);
env.put(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_CONTEXT_FACTORY_CLASS);
env.put(Context.PROVIDER_URL, providerUrl);
env.put(Context.URL_PKG_PREFIXES, DEFAULT_URL_PREFIXES);
return new InitialContext(env);
}
Now, when I change the JNDI bind port from 1099 in server/conf/jboss-service.xml I can't figure out how to programatically find the correct port for the providerUrl above.
I've dumped System.getProperties() and System.getEnv() and it doesn't appear there.
I'm pretty sure I can set it in server/conf/jndi.properties as well, but I was hoping to avoid another magic config file.
I've tried the HttpNamingContextFactory but that fails "java.net.ProtocolException: Server redirected too many times (20)"
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.HttpNamingContextFactory");
env.put(Context.PROVIDER_URL, "http://" + serverAddress + ":8080/invoker/JNDIFactory");
Any ideas?
The information about the port is stored on JBoss as an MBean property. The problem is that in order to read this property you need an access to MBeans, which requires the port number...
I think that the only way to get this port number is to read the configuration file itself and extract the port number. It is not very elegant, so you may prefere to create in web.xml file for your servlet and store the port number there.
You may also use JBoss HTTP invoker, which tunnels requests to 1099 port through port 8080 (default HTTP port), please note however that you need to secure this connector. In this case the port will be always the same as your HTTP port.

Resources