Skip to content

Commit 7dee2ab

Browse files
committed
Massive refactoring including the ability to run the Java examples against either Alfresco in the cloud or Alfresco on-premise (4.2.d or higher)
1 parent e357dff commit 7dee2ab

31 files changed

+733
-578
lines changed
File renamed without changes.

alfresco-api-examples/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
These are simple examples showing how to exercise the Alfresco Public API. With
2+
the release of Alfresco 4.2.d Community Edition, the Public API is now
3+
available on both Alfresco in the cloud and Alfresco on-premise. The difference
4+
is how authentication works and the base part of the URLs.
5+
6+
You can run these examples against either Alfresco in the cloud or your own
7+
Alfresco server, it is completely up to you.
8+
9+
To run a given example against Alfresco in the cloud, change the example class to
10+
extend from BaseCloudExample.
11+
12+
To run a given example against Alfresco on-premise, change the example class to extend
13+
from BaseOnPremExample.
14+
15+
Before running either example
16+
=============================
17+
18+
In BasePublicAPIExample.java, set SITE to a test site ID in which you can
19+
create and delete folders and documents.
20+
21+
Before running against Alfresco in the cloud
22+
============================================
23+
24+
Before running these examples you must first register at:
25+
https://developer.alfresco.com
26+
27+
Add your auth key and secret to OAuth2ClientCredentials.java.
28+
29+
In your application profile on developer.alfresco.com, you must set
30+
your callback URL to http://127.0.0.1:8080/Callback.
31+
32+
If you want to use a different host, port, or URL for your callback,
33+
you must make the appropriate change to LocalServerReceiver.java.
34+
35+
Before running against Alfresco on-premise
36+
==========================================
37+
38+
In BaseOnPremExample.java, set these to match your environment:
39+
40+
* ALFRESCO_API_URL: May need to adjust hostname and port number.
41+
* USER_NAME: Use a username that has an account in Alfresco with access to the
42+
SITE you specified earlier.
43+
* PASSWORD: Password for that account.

alfresco-cloud-example/pom.xml renamed to alfresco-api-examples/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22
<modelVersion>4.0.0</modelVersion>
3-
<groupId>alfresco-cloud-example</groupId>
4-
<artifactId>alfresco-cloud-example</artifactId>
3+
<groupId>alfresco-api-examples</groupId>
4+
<artifactId>alfresco-api-examples</artifactId>
55
<version>0.0.1-SNAPSHOT</version>
66
<build>
77
<sourceDirectory>src/main/java</sourceDirectory>
@@ -37,7 +37,7 @@
3737
<dependency>
3838
<groupId>com.google.oauth-client</groupId>
3939
<artifactId>google-oauth-client</artifactId>
40-
<version>1.13.1-beta</version>
40+
<version>1.16.0-rc</version>
4141
</dependency>
4242
<dependency>
4343
<groupId>javax.servlet</groupId>
@@ -58,7 +58,7 @@
5858
<dependency>
5959
<groupId>org.apache.chemistry.opencmis</groupId>
6060
<artifactId>chemistry-opencmis-client-impl</artifactId>
61-
<version>0.8.0-SNAPSHOT</version>
61+
<version>0.9.0</version>
6262
</dependency>
6363
<dependency>
6464
<groupId>org.alfresco.cmis.client</groupId>
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package com.alfresco.api.example;
2+
3+
import java.awt.Desktop;
4+
import java.awt.Desktop.Action;
5+
import java.io.IOException;
6+
import java.net.URI;
7+
import java.util.Arrays;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
import org.apache.chemistry.opencmis.client.api.Repository;
13+
import org.apache.chemistry.opencmis.client.api.Session;
14+
import org.apache.chemistry.opencmis.client.api.SessionFactory;
15+
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
16+
import org.apache.chemistry.opencmis.commons.SessionParameter;
17+
import org.apache.chemistry.opencmis.commons.enums.BindingType;
18+
19+
import com.alfresco.api.example.oauth.LocalServerReceiver;
20+
import com.alfresco.api.example.oauth.OAuth2ClientCredentials;
21+
import com.alfresco.api.example.oauth.VerificationCodeReceiver;
22+
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
23+
import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl;
24+
import com.google.api.client.auth.oauth2.BearerToken;
25+
import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
26+
import com.google.api.client.auth.oauth2.Credential;
27+
import com.google.api.client.auth.oauth2.TokenResponse;
28+
import com.google.api.client.http.GenericUrl;
29+
import com.google.api.client.http.HttpRequest;
30+
import com.google.api.client.http.HttpRequestFactory;
31+
import com.google.api.client.http.HttpRequestInitializer;
32+
import com.google.api.client.http.HttpTransport;
33+
import com.google.api.client.http.javanet.NetHttpTransport;
34+
import com.google.api.client.json.JsonFactory;
35+
import com.google.api.client.json.JsonObjectParser;
36+
import com.google.api.client.json.jackson.JacksonFactory;
37+
38+
/**
39+
* This class contains only the logic specific to using the Alfresco Public API
40+
* against Alfresco in the cloud.
41+
*
42+
* @author jpotts
43+
*/
44+
public class BaseCloudExample extends BasePublicAPIExample {
45+
46+
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
47+
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
48+
49+
public static final String ALFRESCO_API_URL = "https://api.alfresco.com/";
50+
51+
public static final String TOKEN_SERVER_URL = ALFRESCO_API_URL + "auth/oauth/versions/2/token";
52+
public static final String AUTHORIZATION_SERVER_URL = ALFRESCO_API_URL + "auth/oauth/versions/2/authorize";
53+
public static final String SCOPE = "public_api";
54+
55+
private HttpRequestFactory requestFactory;
56+
private Credential credential;
57+
58+
public String getAtomPubURL() {
59+
return ALFRESCO_API_URL + "cmis/versions/1.0/atom";
60+
}
61+
62+
public void launchInBrowser(
63+
String browser, String redirectUrl, String clientId, String scope) throws IOException {
64+
65+
String authorizationUrl = new AuthorizationCodeRequestUrl(
66+
AUTHORIZATION_SERVER_URL, clientId).setRedirectUri(redirectUrl)
67+
.setScopes(Arrays.asList(scope)).build();
68+
69+
if (Desktop.isDesktopSupported()) {
70+
Desktop desktop = Desktop.getDesktop();
71+
if (desktop.isSupported(Action.BROWSE)) {
72+
desktop.browse(URI.create(authorizationUrl));
73+
return;
74+
}
75+
}
76+
77+
if (browser != null) {
78+
Runtime.getRuntime().exec(new String[] {browser, authorizationUrl});
79+
} else {
80+
System.out.println("Open the following address in your favorite browser:");
81+
System.out.println(" " + authorizationUrl);
82+
}
83+
}
84+
85+
/**
86+
* Does the OAuth dance by starting up a local server to handle the
87+
* redirect. The credential gets saved off because it needs to be used
88+
* when/if a CMIS session is needed.
89+
*
90+
* @return HttpRequestFactory
91+
*/
92+
public HttpRequestFactory getRequestFactory() {
93+
if (this.requestFactory == null) {
94+
VerificationCodeReceiver receiver = new LocalServerReceiver();
95+
try {
96+
String redirectUri = receiver.getRedirectUri();
97+
launchInBrowser("google-chrome", redirectUri, OAuth2ClientCredentials.CLIENT_ID, SCOPE);
98+
this.credential = authorize(receiver, redirectUri);
99+
100+
this.requestFactory = HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
101+
@Override
102+
public void initialize(HttpRequest request) throws IOException {
103+
credential.initialize(request);
104+
request.setParser(new JsonObjectParser(new JacksonFactory()));
105+
}
106+
});
107+
108+
System.out.println("Access token:" + credential.getAccessToken());
109+
110+
} catch (Exception e) {
111+
e.printStackTrace();
112+
} finally {
113+
try {
114+
receiver.stop();
115+
} catch (Exception e) {}
116+
}
117+
}
118+
return this.requestFactory;
119+
}
120+
121+
public Credential authorize(VerificationCodeReceiver receiver, String redirectUri)
122+
throws IOException {
123+
124+
String code = receiver.waitForCode();
125+
126+
AuthorizationCodeFlow codeFlow = new AuthorizationCodeFlow.Builder(
127+
BearerToken.authorizationHeaderAccessMethod(),
128+
HTTP_TRANSPORT,
129+
JSON_FACTORY,
130+
new GenericUrl(TOKEN_SERVER_URL),
131+
new ClientParametersAuthentication(
132+
OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.CLIENT_SECRET),
133+
OAuth2ClientCredentials.CLIENT_ID,
134+
AUTHORIZATION_SERVER_URL).setScopes(SCOPE).build();
135+
136+
TokenResponse response = codeFlow.newTokenRequest(code)
137+
.setRedirectUri(redirectUri).setScopes(SCOPE).execute();
138+
139+
return codeFlow.createAndStoreCredential(response, null);
140+
141+
}
142+
143+
/**
144+
* Gets a CMIS Session by connecting to the Alfresco Cloud.
145+
*
146+
* @param accessToken
147+
* @return Session
148+
*/
149+
public Session getCmisSession() {
150+
String accessToken = getCredential().getAccessToken();
151+
System.out.println("Access token:" + accessToken);
152+
153+
// default factory implementation
154+
SessionFactory factory = SessionFactoryImpl.newInstance();
155+
Map<String, String> parameter = new HashMap<String, String>();
156+
157+
// connection settings
158+
parameter.put(SessionParameter.ATOMPUB_URL, this.getAtomPubURL());
159+
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
160+
parameter.put(SessionParameter.AUTH_HTTP_BASIC, "false");
161+
parameter.put(SessionParameter.HEADER + ".0", "Authorization: Bearer " + accessToken);
162+
parameter.put(SessionParameter.OBJECT_FACTORY_CLASS, "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl");
163+
164+
List<Repository> repositories = factory.getRepositories(parameter);
165+
166+
return repositories.get(0).createSession();
167+
}
168+
169+
public Credential getCredential() {
170+
if (this.credential == null) {
171+
getRequestFactory(); // Yuck, depending on a side-effect
172+
}
173+
return this.credential;
174+
}
175+
176+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.alfresco.api.example;
2+
3+
import java.io.IOException;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import org.apache.chemistry.opencmis.client.api.Repository;
9+
import org.apache.chemistry.opencmis.client.api.Session;
10+
import org.apache.chemistry.opencmis.client.api.SessionFactory;
11+
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
12+
import org.apache.chemistry.opencmis.commons.SessionParameter;
13+
import org.apache.chemistry.opencmis.commons.enums.BindingType;
14+
15+
import com.google.api.client.http.HttpRequest;
16+
import com.google.api.client.http.HttpRequestFactory;
17+
import com.google.api.client.http.HttpRequestInitializer;
18+
import com.google.api.client.http.HttpTransport;
19+
import com.google.api.client.http.javanet.NetHttpTransport;
20+
import com.google.api.client.json.JsonFactory;
21+
import com.google.api.client.json.JsonObjectParser;
22+
import com.google.api.client.json.jackson.JacksonFactory;
23+
24+
/**
25+
* This class contains only the logic that is specific to using the Public API
26+
* against an Alfresco repository running on-premise (4.2.d or later).
27+
*
28+
* @author jpotts
29+
*/
30+
public class BaseOnPremExample extends BasePublicAPIExample {
31+
32+
/**
33+
* Change these to match your environment
34+
*/
35+
public static final String ALFRESCO_API_URL = "http://localhost:8080/alfresco/api/";
36+
public static final String USER_NAME = "admin";
37+
public static final String PASSWORD = "admin";
38+
39+
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
40+
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
41+
42+
private HttpRequestFactory requestFactory;
43+
44+
public String getAtomPubURL(HttpRequestFactory requestFactory) {
45+
String atomPubURL = null;
46+
47+
try {
48+
atomPubURL = ALFRESCO_API_URL + getHomeNetwork(ALFRESCO_API_URL, requestFactory) + "/public/cmis/versions/1.0/atom";
49+
} catch (IOException ioe) {
50+
atomPubURL = "-default-";
51+
}
52+
53+
return atomPubURL;
54+
}
55+
56+
/**
57+
* Gets a CMIS Session by connecting to the local Alfresco server.
58+
*
59+
* @return Session
60+
*/
61+
public Session getCmisSession() {
62+
// default factory implementation
63+
SessionFactory factory = SessionFactoryImpl.newInstance();
64+
Map<String, String> parameter = new HashMap<String, String>();
65+
66+
// connection settings
67+
parameter.put(SessionParameter.ATOMPUB_URL, getAtomPubURL(getRequestFactory()));
68+
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
69+
parameter.put(SessionParameter.AUTH_HTTP_BASIC, "true");
70+
parameter.put(SessionParameter.USER, USER_NAME);
71+
parameter.put(SessionParameter.PASSWORD, PASSWORD);
72+
parameter.put(SessionParameter.OBJECT_FACTORY_CLASS, "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl");
73+
74+
List<Repository> repositories = factory.getRepositories(parameter);
75+
76+
return repositories.get(0).createSession();
77+
}
78+
79+
/**
80+
* Uses basic authentication to create an HTTP request factory.
81+
*
82+
* @return HttpRequestFactory
83+
*/
84+
public HttpRequestFactory getRequestFactory() {
85+
if (this.requestFactory == null) {
86+
this.requestFactory = HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
87+
@Override
88+
public void initialize(HttpRequest request) throws IOException {
89+
request.setParser(new JsonObjectParser(new JacksonFactory()));
90+
request.getHeaders().setBasicAuthentication(USER_NAME, PASSWORD);
91+
}
92+
});
93+
}
94+
return this.requestFactory;
95+
}
96+
}

0 commit comments

Comments
 (0)