Power to the People – Customize and Extend Artifactory with User Plugins
From our experience with thousands of Artifactory users, we know one thing for sure:we don’t know better. Every organization does its ALM differently: artifact approval flow, snapshot retention policies, build-to-release flow, governance, required metadata and much, much more – each organization is different. We definitely have some ideas on how the build and deploy process should look, but there are so many things that make your process unique. And that’s good. After all, you aren’t paid for working within the ideal deployment cycle, but rather for solving a business problem. At least we hope so.
Acknowledging the fact that we don’t know better complicates our lives as creators of a binary repository… and not only by hurting our ego. We want to give you the perfect tool for the job, but how can we do it without dictating to you what your job is? The solution is well known – extensions, a.k.a. add-ons, user plugins, you name it.
“OMG!”, you might say. “Code! Joy-joy! Finally, an excuse to hack around!” Or “OMG! Code! It’s your job to code those things into your product, not mine!” Look, either way, we don’t have much choice, do we? When it comes to customization, you have to tell Artifactory what you want it to do. We can only do our best to make it simple for you. So, we developed a simple DSL.
In this post, I’ll show you how easy it is to customize Artifactory with user plugins. Here’s the story: you want to prevent the download of deprecated artifacts. The deprecation information is attached as a set of custom properties to the artifacts by some quality-assurance mechanism (or organism).
Let’s say, for example, the artifacts to be banned from download are annotated with propertydeprecated=true
. Artifactory allows you to code callbacks that will be executed in response to various events in the system. You can find the list of available callbacks in the User Plugins documentation. So, we are going to write a download
plugin and the callback we are looking for is the altResponse
. In this callback, we can provide an alternative response instead of the one Artifactory was asked for. Here’s the code:
1 download { 2 altResponse { request, responseRepoPath -> 3 def deprecated = repositories.getProperties(responseRepoPath).getFirst('deprecated')
4 if(deprecated && deprecated.toBoolean()) { 5 status= 403 6 message= 'This artifact was deprecated, please use some alternative.'
7 log.warn "Request was made for deprecated artifact: $responseRepoPath.";
8 } 9 } 10 }
So, here we go, line by line:
- Declares that it’s a
download
plugin. - Defines the callback type we want (
altResponse
). When we implement the alternative response, Artifactory provides us with 2 objects:- The
request
, an instance oforg.artifactory.request.Request
. It encapsulates the information about the incoming request, such as client details and the information requested - And
responseRepoPath
, an instance oforg.artifactory.repo.RepoPath
. It encapsulates the information about the artifact to be returned.
- The
- We want the first value of the
'deprecated'
property, if defined on the artifact represented byresponseRepoPath
. - If the value exists and it is
'true'
,1
or'y'
(as declared by Groovy’stoBoolean()
) - set return code to 403 (Forbidden) and
- set the correct error message and
- optionally, issue a warning to the Artifactory log.
Enjoy your build!