JIRA Rest Service with Bandana Manager - spring

I have a JIRA plugin that I'm developing that has a REST service. That service should be able to accept POSTed requests, unmarshall some data and store it. The seemingly suggested way to do this in JIRA is to make use of the Bandana persistence framework. According to this page, I should be able to simply define a setter that Spring should call to give me my Bandana manager.
#Path("/path")
public class SCMService {
private BandanaManager bandanaManager;
// setter called by Spring
public void setBandanaManager(BandanaManager bandanaManager) {
this.bandanaManager = bandanaManager;
}
//...More methods...
}
However, when I test this, the setter is never being called and my manager is null. I'm guessing this should be as simple as registering this service with Spring for injection somehow but I can't seem to find anything like that.
How would I get my setter called? Is there a better way to do this?

Er, I'm not sure that JIRA uses Bandana in that way, though Confluence does. You can certainly post data to a JIRA rest resource and then store it using properties tables
Something like this:
#POST
#Consumes (MediaType.APPLICATION_XML)
public Response createComponentAndIssues(#Context HttpServletRequest request, ...

Related

Spring Boot: Retrieve config via rest call upon application startup

I d like to make a REST call once on application startup to retrieve some configuration parameters.
For example, we need to retrieve an entity called FleetConfiguration from another server. I d like to do a GET once and save the keep the data in memory for the rest of the runtime.
What s the best way of doing this in Spring? using Bean, Config annotations ..?
I found this for example : https://stackoverflow.com/a/44923402/494659
I might as well use POJOs handle the lifecycle of it myself but I am sure there s a way to do it in Spring without re-inventing the wheel.
Thanks in advance.
The following method will run once the application starts, call the remote server and return a FleetConfiguration object which will be available throughout your app. The FleetConfiguration object will be a singleton and won't change.
#Bean
#EventListener(ApplicationReadyEvent.class)
public FleetConfiguration getFleetConfiguration(){
RestTemplate rest = new RestTemplate();
String url = "http://remoteserver/fleetConfiguration";
return rest.getForObject(url, FleetConfiguration.class);
}
The method should be declared in a #Configuration class or #Service class.
Ideally the call should test for the response code from the remote server and act accordingly.
Better approach is to use Spring Cloud Config to externalize every application's configuration here and it can be updated at runtime for any config change so no downtime either around same.

Mule connector config needs dynamic attributes

I have develop a new Connector. This connector requires to be configured with two parameters, lets say:
default_trip_timeout_milis
default_trip_threshold
Challenge is, I want read ${myValue_a} and ${myValue_a} from an API, using an HTTP call, not from a file or inline values.
Since this is a connector, I need to make this API call somewhere before connectors are initialized.
FlowVars aren't an option, since they are initialized with the Flows, and this is happening before in the Mule app life Cycle.
My idea is to create an Spring Bean implementing Initialisable, so it will be called before Connectors are init, and here, using any java based libs (Spring RestTemplate?) , call API, get values, and store them somewhere (context? objectStore?) , so the connector can access them.
Make sense? Any other ideas?
Thanks!
mmm you could make a class that will create the properties in the startup and in this class obtain the API properties via http request. Example below:
public class PropertyInit implements InitializingBean,FactoryBean {
private Properties props = new Properties();
#Override
public Object getObject() throws Exception {
return props;
}
#Override
public Class getObjectType() {
return Properties.class;
}
}
Now you should be able to load this property class with:
<context:property-placeholder properties-ref="propertyInit"/>
Hope you like this idea. I used this approach in a previous project.
I want to give you first a strong warning on doing this. If you go down this path then you risk breaking your application in very strange ways because if any other components depend on this component you are having dynamic components on startup, you will break them, and you should think if there are other ways to achieve this behaviour instead of using properties.
That said the way to do this would be to use a proxy pattern, which is a proxy for the component you recreate whenever its properties are changed. So you will need to create a class which extends Circuit Breaker, which encapsulates and instance of Circuit Breaker which is recreated whenever its properties change. These properties must not be used outside of the proxy class as other components may read these properties at startup and then not refresh, you must keep this in mind that anything which might directly or indirectly access these properties cannot do so in their initialisation phase or your application will break.
It's worth taking a look at SpringCloudConfig which allows for you to have a properties server and then all your applications can hot-reload those properties at runtime when they change. Not sure if you can take that path in Mule if SpringCloud is supported yet but it's a nice thing to know exists.

How to generate Java client proxy for RESTful service implemented with Spring?

We use Spring to implement REST controller, for example:
#Controller
#RequestMapping("/myservice")
public class MyController {
#RequestMapping(value = "foo", method = RequestMethod.GET)
public #ResponseBody string foo() {...}
}
I can call this service using spring RestTemplate, and it works fine, but I would prefer to invoke it using a proxy, instead of typeless invocation using string url:
// client code:
MyController proxy = getProxy("baseUrl", MyController.class);
String results = proxy.foo();
So the input to proxy generation is java interface with annotations describing REST details.
I read this article and it looks like all types of remote calls do have proxies, and all I need for REST is something like RestProxyFactoryBean, that would take my REST java interface and return type-safe proxy that uses RestTemplate as implementation.
The closest solution I found is JBoss RESTEasy.
But it seems to use different set of annotations, so I am not sure it will work with annotations I already have: #Controller, #RequestMapping.
Are there other options, or RESTEasy is the only one?
Note, I am spring newbie so some obvious spring things are pretty new to me.
Thank you.
Dima
You can try Feign by Netflix, a lightweight proxy-based REST client. It works declaratively through annotations, and it's used by Spring Cloud projects to interact with Netflix Eureka.
One of the reasons the REST paradigm was invented was because expirience with other remoting technologies (RMI, CORBA, SOAP) shows us that often, the proxy-based approach creates more problems than it solves.
Theoretically, a proxy makes the fact that a function call is remote transparent to its users, so they can use the function exactly the same way as if it were a local function call.
In practice however this promise cannot be fulfilled, because remote function calls simply have other properties than local calls. Network outages, congestion, timeouts, load problems to name just a few. If you choose to ignore all these things that can go wrong with remote calls, your code probably won't be very stable.
TL;DR: You probably shouldn't work with a proxy, it's not state of the art any more. Just use RestTemplate.
Here is a project trying to generate runtime proxies from the controller annotations (using RestTemplate in the background to handle proxy calls): spring-rest-proxy-client Very early in implementation though.
This seems to do it: https://swagger.io/swagger-codegen/, and swagger has many other nice things for REST API.
Have a look at https://github.com/ggeorgovassilis/spring-rest-invoker.
All you need is to register FactoryBean:
#Configuration
public class MyConfiguration {
#Bean
SpringRestInvokerProxyFactoryBean BankService() {
SpringRestInvokerProxyFactoryBean proxyFactory = new SpringRestInvokerProxyFactoryBean();
proxyFactory.setBaseUrl("http://localhost/bankservice");
proxyFactory.setRemoteServiceInterfaceClass(BankService.class);
return proxyFactory;
}
and after that you can autowire the interface class:
#Autowired
BookService bookService;
I also ended up making my own library for this. I wanted something that is as small as possible, adds only itself to classpath and no transitive dependencies.
A client is created like:
final StoreApi storeApi = SpringRestTemplateClientBuilder
.create(StoreApi.class)
.setRestTemplate(restTemplate)
.setUrl(this.getMockUrl())
.build();
And rest-requests will be performed when invoking the methods:
storeApi.deleteOrder(1234L);
The is supports both method signatures:
ResponseEntity<X> deleteOrder(Long)
X deleteOrder(Long)

Available paths listing for Spring actions

I have an application which exposes RESTful actions using spring annotations and Spring MVC.
It looks like
#RequestMapping(value = "/example/{someId}",
method = RequestMethod.GET, consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public void isRegisteredToThread(#PathVariable long someId, HttpServletResponse response) {
[something]
}
What I want is an automatically generated listing of all URL's, methods and available parameters - possibly within a WSDL. Is there a plugin or is it somehwere available?
WSDL is not done for rest, it's used for SOAP.
You might use WADL, but I really do not suggest it.
In my project I always use swagger (there is a release for spring). You may find more info here https://github.com/martypitt/swagger-springmvc and here http://blog.zenika.com/index.php?post/2013/07/11/Documenting-a-REST-API-with-Swagger-and-Spring-MVC
Give it a try.
As an alternative, if you don't need something web-based, you may try rest-shell (https://github.com/spring-projects/rest-shell)
You could take a look at the source code of RequestMappingEndpoint provided by the Spring Boot and see how Spring Boot reports the mappings.
Looking through that code one can see that the mappings (both handler and method mappings) can easily be obtained from the applicationContext
(using
applicationContext.getBeansOfType(AbstractUrlHandlerMapping.class)
and
applicationContext.getBeansOfType(AbstractHandlerMethodMapping.class)
respectively). After you have obtained the mapping you can process them anyway you like.
You might want to create a library that could include in all your projects that processes the mapping your organizations desired form

Can I use expressions in Apache Shiro security annotations?

I've been doing some comparisons between Apache Shiro and Spring Security - I'm really loving the security model that Shiro uses and believe it to be far cleaner that Spring Security.
However, one big nice-to-have would be to be able to reference method parameters from within the method-level security annotations. For example, right now I could so something like:
#RequiresPermissions("account:send:*")
public void sendEmail( EmailAccount account, String to, String subject, String message) { ... }
Within the context of this example, this means that the authenticated user must have the permission to send emails on email accounts.
However, this is not fine-grained enough, as I want instance level permissions! In this context, assume that users can have permissions on instances of email accounts. So, I'd like to write the previous code something like this:
#RequiresPermissions("account:send:${account.id}")
public void sendEmail( EmailAccount account, String to, String subject, String message) { ... }
In this way, the permission string is referencing a parameter passed into the method such that the method can be secured against a particular instance of EmailAccount.
I know I could easily do this from plain Java code within the method, but it would be great to achieve the same thing using annotations - I know Spring Security supports Spring EL expressions in its annotations.
Is this definitely not a feature of Shiro and thus will I have to write my own custom annotations?
Thanks,
Andrew
Look at the classes in http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authz/aop/package-summary.html, especially PermissionAnnotationHandler. There you can see that all Shiro does when encountering the #RequiresPermissions annotation is call getSubject().isPermitted(permission) and does no substitution inside the annotation value at all. You would have to somehow override that handler if you wanted this kind of functionality.
So to answer your question: yes, this is definitely not a feature of Shiro and you have to either write your own annotation or somehow override that handler.
This feature is currently not supported by Shiro. Multiple people have requested this feature. Perhaps we can vote for the issue?
https://issues.apache.org/jira/browse/SHIRO-484
https://issues.apache.org/jira/browse/SHIRO-77
https://issues.apache.org/jira/browse/SHIRO-417
https://issues.apache.org/jira/browse/SHIRO-331

Resources