Hello,
I am beginning a project where the goal is to upload a document to a folder on my company's confluence site. I have been researching what REST API's and services there are that could help me with my problem. I feel like I have gotten close but am just missing the mark and cannot figure what to do. I have looked through a lot of documentation that has been provided by Atlassian but I have either not been looking in the right place or I just went over something along the way. Can anyone point in the right direction on where I should start? I am attempting to do this within Java. I am new to Confluence and Atlassian so I have no idea if this is possible.
Thanks in advance
Community moderators have prevented the ability to post new answers.
Tiago and Gorka,
I appreciate both of your assistance. I did figure out how to upload an attachment to a Confluence page in Java. While I didn't use your methods specifically I'll give you both upvotes for your time and because while they didn't quite fit what I was looking for I know it will help someone else out there. And trying both of your methods spurred my thinking and got me going. My method is similar to Bob Swifts method found here: https://bobswift.atlassian.net/secure/attachmentzip/unzip/20314/18100%5B4%5D/confluence-soap-examples/ExampleClientGetServerInfo.java
If you find you are getting weird SSL Exception errors that means you need to add your Confluence's security certificate to your cacerts file. You can find more details on that here: https://confluence.atlassian.com/display/JIRAKB/Unable+to+Connect+to+SSL+Services+due+to+PKIX+Path+Building+Failed+sun.security.provider.certpath.SunCertPathBuilderException
Here's what I did:
ConfluenceSoapServiceServiceLocator fConfluenceSoapServiceGetter = new ConfluenceSoapServiceServiceLocator(); ConfluenceSoapService service = null; String fToken = null; // This prevents Java from fatal error because it doesn't recognizes Confluence's security certificate. May have to your Confluence sites security certificate to your cacerts file System.setProperty("jsse.enableSNIExtension", "false"); try { // find endpoint on Confluence to work with and get Services from Confluence String endPoint = "/plugins/servlet/soap-axis1/confluenceservice-v2"; fConfluenceSoapServiceGetter.setConfluenceserviceV2EndpointAddress("https://confluence.<companynamehere>.com" + endPoint); fConfluenceSoapServiceGetter.setMaintainSession(true); service = fConfluenceSoapServiceGetter.getConfluenceserviceV2(); // Authenticate user fToken = service.login(username, password); // Read file to be uploaded to Confluence FileInputStream fis = null; File in = new File(sourceLoc); fis = new FileInputStream(in); byte[] buf = new byte[4096]; byte[] fbuf = new byte[(int) in.length()]; int c = 0; int length = 0; logger.debug("Reading: " + in.getAbsolutePath()); while((length = fis.read(buf)) > 0) { System.arraycopy(buf, 0, fbuf, c, length); c += length; } // Gather information necessary to upload file RemoteAttachment ra = new RemoteAttachment(); ra.setFileName(reportName); ra.setCreator(creator); ra.setFileSize(length); ra.setContentType("txt"); // Uploads file to Confluence. PageId is of the page you want to put the attachment on service.addAttachment(fToken, pageId, ra, fbuf); } catch (Exception e) { e.printStackTrace(); }
Nice! I'm glad you did it!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi James,
Using what Tiago posted, you can create a POST request from java
User adminUser = userManager.getUser("admin"); ConfluenceUser confluenceAdminUser = new ConfluenceUserImpl(adminUser); AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser); Request request = requestFactory.createRequest(Request.MethodType.POST, restUrl); request.addTrustedTokenAuthentication(); request.execute();
Depending on what you need, you can set the content type or the body of the request
request.setRequestContentType(...); request.setRequestBody(...);
or even handle the response
request.execute(new ResponseHandler() { @Override public void handle(Response response) throws ResponseException { System.out.println(response.getStatusCode()); } });
Hope this gives you a hint about how to follow!
Gorka
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for this Gorka. Do you know which jar contains "User" and where I can find that? And is the variable "userManager" of type UserManager? What are the other dependencies for this code?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi James,
The jar containing com.atlassian.user.User is atlassian-user-3.0.jar but I think it comes with the core. UserManager has to be injected in your constructor
public YourClass(UserManager userManager){ this.userManager = userManager; }
For the rest of dependencies, I think the following should be enough
atlassian-plugin.xml
<component-import key="userManager" interface="com.atlassian.sal.api.user.UserManager" />
<component key="compatibilityUserManager" class="com.atlassian.sal.usercompatibility.impl.CompatibilityUserManager" />
<component-import key="salRequestFactory" interface="com.atlassian.sal.api.net.RequestFactory" />
Your pom.xml
<dependency>
<groupId>com.atlassian.usercompatibility</groupId>
<artifactId>usercompatibility-sal</artifactId>
<version>${usercompatibility.version}</version>
</dependency>
<dependency> <groupId>com.atlassian.sal</groupId> <artifactId>sal-api</artifactId> <version>${sal.api.version}</version> <scope>provided</scope> </dependency>
... <properties> ... <sal.api.version>2.8.0</sal.api.version> <usercompatibility.version>0.5</usercompatibility.version>
</properties>
Check it and post the result!
Gorka
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I've never used User or UserManager before and am having some trouble with it. Do you think you could give me a little explanation on them? Not sure how to get it setup. Thanks
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Could you be a little more specific? What troubles are you having now?
Gorka
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I get that the adminUser contains credentials for the confluence site I am trying to post to. I do not know how to assign said credentials to the adminUser. It appears it is done with the UserManager but I can't quite figure out how to do it.
Thanks again
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi James,
In the example I gave to you
User adminUser = userManager.getUser("admin"); ConfluenceUser confluenceAdminUser = new ConfluenceUserImpl(adminUser); AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser); Request request = requestFactory.createRequest(Request.MethodType.POST, restUrl); request.addTrustedTokenAuthentication(); request.execute();
Check this line
AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser);
A simple ThreadLocal to store the currently authenticated user. This can be used when the user comes from something other than the web interface (i.e. SOAP).
Extracted from https://docs.atlassian.com/atlassian-confluence/latest/com/atlassian/confluence/user/AuthenticatedUserThreadLocal.html
Did you try it? If it worked like Tiago said, I suppose it should work this way. You are doing the same, a POST request.
Regards,
Gorka
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi James, have you tried to upload your attachments using this REST call?
curl -D- -u user:password -X POST -H "X-Atlassian-Token: nocheck" -F "file=@test.txt" http://<confluence_url>/rest/api/content/<page_id>/child/attachment
The output of it should be something like this:
HTTP/1.1 100 Continue HTTP/1.1 100 Continue HTTP/1.1 200 OK Date: Tue, 02 Sep 2014 14:21:34 GMT Server: Apache-Coyote/1.1 X-ASEN: SEN-L4138508 X-Seraph-LoginReason: OK X-AUSERNAME: admin X-Content-Type-Options: nosniff Content-Type: application/json Set-Cookie: JSESSIONID=6BE16241C81BAAA2F19B7ECBBD4D1A58; Path=/confluence/; HttpOnly Connection: close Transfer-Encoding: chunked {"results":[{"id":"att9797634","type":"attachment","title":"test.txt","version":{"by":{"type":"known","profilePicture":{"path":"/confluence/s/en_GB/5510/701ab0bfc8a95d65a5559a923f8ed8badd272d36.1/_/images/icons/profilepics/default.png","width":48,"height":48,"isDefault":true},"username":"admin","displayName":"Administrator"},"when":"2014-09-02T11:21:34.019-0300","number":1,"minorEdit":false},"container":{"id":"9502724","type":"page","title":"content test","_links":{"webui":"/display/CS/content+test","tinyui":"/x/BACR","self":"https://ironman/confluence/rest/api/content/9502724"},"_expandable":{"history":"/rest/api/content/9502724/history","body":"","container":"","ancestors":"","children":"/rest/api/content/9502724/child","descendants":"/rest/api/content/9502724/descendant","space":"/rest/api/space/CS","version":"","metadata":""}},"metadata":{"mediaType":"application/octet-stream"},"_links":{"download":"/download/attachments/9502724/test.txt?version=1&modificationDate=1409667694019&api=v2","webui":"/pages/viewpageattachments.action?pageId=9502724&highlight=test.txt#content+test-attachment-test.txt","self":"https://ironman/confluence/rest/api/content/att9797634"},"_expandable":{"history":"/rest/api/content/att9797634/history","body":"","ancestors":"","children":"/rest/api/content/att9797634/child","descendants":"/rest/api/content/att9797634/descendant","space":"/rest/api/space/CS"}}],"size":1}
I hope it helps.
Cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I have not, I am actually trying to do this within Java. I did not mention that in the original post, my apologies. I will fix that. Do you know how to do this in Java?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Tiago, I tried running this and it returned the html of the confluence page. Would you know why this happens?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I got:
HTTP/1.1 100 Continue
HTTP/1.1 100 Continue
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Do you know what's the http response? for example, in the command output above the response was HTTP
/1
.1 200 OK
, which is the expected one when everything is alright.
Cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
404 means that your URL wasn't found. In the command line above you'll see the example http://<confluence_url>/rest/api/content/<page_id>/child/attachment, which in my case the actual URL was: https://ironman/confluence/rest/api/content/8814611/child/attachment, you may want to confirm your URL.
Cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I am definitely going wrong with the <confluence_url> portion. To me it seems like it should be the full url of the page I want to upload a document to. But your example only has "ironman/confluence" as the "<confluence_url>". Is there anything you can explain about this portion? I appreciate all the help by the way
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I am also now getting a HTTP 302 response now. Isn't that some form of redirect?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sure, ironman is a DNS alias (cname) to one of our test servers and the portion "confluence" is a context path that was defined to this confluence instance. So if I want to access Confluence dashboad I'd use https://ironman/confluence
I hope it helps to clarify, let me know if you need any additional info.
Cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
So I just don't know enough about these rest services, DNS servers and Confluence but the Confluence instance I am working in is only accessible online through a https://confluence.<companynamehere>.com/display/<destinationfolder>. Based on your previous comment it seems like I can't just use that URL I just put here to complete the CURL command. Does it only work with the DNS alias and context path you have defined? Would I have to do the same thing. I'm sorry if I sound uneducated about this stuff but the truth is I am. I just want to make sure were on the same page and there's not more setup required on my end.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, this gives me the HTTP 404 as the third HTTP message just like before. Then it spits back the html of that confluence page. I am also using a -k for a parameter because of an issue with the security certificate so I'm just bypassing it. Would that affect anything? Other than that I did exactly what you suggested
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This is the exact command I am using
curl -D- -u <user>:<password> -X POST -H "X-Atlassian-Token: no-check" -F "file=@C:\DEV\TestFile2.txt" https://confluence.<companynameher>.com/rest/api/content/<pageid>/child/attachment-k
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Actually it's not necesary to define DNS alias or context path, sorry I may have caused this confusion, my intention was just explain how my URL was built.
Based on your comment it seems that the URL in your curl command should be https://confluence.<companynamehere>.com/rest/api/content/<page_id>/child/attachment, have you tried this format?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.