I'm trying to send a file using zoom api, and I have a OAuth server-to-server authentication with /chat_message:write:admin in my app scope and I have tested simple message without problems. I already have a token, my ID and my recipient's ID.
My program runs and returns error 405 method not allowed.
I choose to send label.pdf file.
Zoom documentation page is: link to zoom api send document
private static final String API_ENDPOINT = "https://api.zoom.us/v2/chat/users/";
// Create API URL
URL url = new URL(API_ENDPOINT + userId + "/messages/files");
// Open connection and set request properties
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + token);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=boundary");
byte[] pdfData = Files.readAllBytes(new File(filePath).toPath());
String boundary = "boundary";
String delimiter = "--" + boundary + "\r\n";
StringBuilder builder = new StringBuilder();
builder.append(delimiter);
builder.append("Content-Disposition: form-data; name=\"to_contact\"\r\n\r\n");
builder.append(toContact+"\r\n");
builder.append(delimiter);
builder.append("Content-Disposition: form-data; name=\"files\"; filename=\"label\"\r\n");
builder.append("Content-Type: application/pdf\r\n");
builder.append("\r\n");
builder.append(new String(pdfData, "ISO-8859-1"));
builder.append("\r\n");
builder.append("--" + boundary + "--");
conn.setDoOutput(true);
String multipartData = builder.toString();
System.out.println(multipartData);
conn.getOutputStream().write(multipartData.getBytes("UTF-8"));
// Send request and get response code and message
conn.connect();
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
// Check if response is successful
if (Arrays.asList(RESPONSE_CODE).contains(Integer.toString(responseCode))) {
System.out.println("File sent successfully!");
System.out.println("Response code: " + responseCode);
System.out.println("Response message: " + responseMessage);
} else {
System.out.println("Error sending file:");
System.out.println("Response code: " + responseCode);
System.out.println("Response message: " + responseMessage);
}
// Close connection
conn.disconnect();
Can anyone suggest me what's wrong?
i got the code snippet of adding a defect to defect suite from forums.
However, my requirement is to pull defect from defect suite and i am not aware of defect suite information.
Is there a way to pull collection of defect suites and defects from it.
Here is the sample code snippet to add defect to defect suite.
> import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.CreateRequest;
import com.rallydev.rest.request.QueryRequest;
import com.rallydev.rest.request.UpdateRequest;
import com.rallydev.rest.response.CreateResponse;
import com.rallydev.rest.response.QueryResponse;
import com.rallydev.rest.response.UpdateResponse;
import com.rallydev.rest.util.Fetch;
import com.rallydev.rest.util.QueryFilter;
import com.rallydev.rest.util.Ref;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class addDefectToSuite {
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "https://rally1.rallydev.com";
String username = "user#company.com";
String password = "secret";
String wsapiVersion = "v2.0";
String projectRef = "/project/12352608219";
String workspaceRef = "/workspace/12352608129";
String applicationName = "Create defect, add to a defectsuite";
RallyRestApi restApi = new RallyRestApi(
new URI(host),
username,
password);
restApi.setWsapiVersion(wsapiVersion);
restApi.setApplicationName(applicationName);
QueryRequest defectSuiteRequest = new QueryRequest("DefectSuite");
defectSuiteRequest.setFetch(new Fetch("FormattedID","Name", "Defects"));
defectSuiteRequest.setWorkspace(workspaceRef);
defectSuiteRequest.setQueryFilter(new QueryFilter("FormattedID", "=", "DS1"));
QueryResponse defectSuiteQueryResponse = restApi.query(defectSuiteRequest);
JsonObject defectSuiteJsonObject = defectSuiteQueryResponse.getResults().get(0).getAsJsonObject();
System.out.println("defectSuiteJsonObject" + defectSuiteJsonObject);
String defectSuiteRef = defectSuiteJsonObject.get("_ref").getAsString();
int numberOfDefects = defectSuiteJsonObject.getAsJsonObject("Defects").get("Count").getAsInt();
System.out.println(defectSuiteJsonObject.get("Name") + " ref: " + defectSuiteRef + "number of defects: " + numberOfDefects + " " + defectSuiteJsonObject.get("Defects"));
try {
JsonObject defect = new JsonObject();
defect.addProperty("Name", "bad defect 668");
CreateRequest createRequest = new CreateRequest("defect", defect);
CreateResponse createResponse = restApi.create(createRequest);
if (createResponse.wasSuccessful()) {
JsonObject defectJsonObject = createResponse.getObject();
String defectRef = Ref.getRelativeRef(createResponse.getObject().get("_ref").getAsString());
System.out.println(String.format("Created %s", defectRef));
JsonObject defectSuitesOfThisDefect = (JsonObject) defectJsonObject.get("DefectSuites");
int numberOfSuites = defectSuitesOfThisDefect.get("Count").getAsInt();
System.out.println("number of defect suites this defect is part of: " + numberOfSuites);
QueryRequest defectSuitesOfThisDefectRequest = new QueryRequest(defectSuitesOfThisDefect);
JsonArray suites = restApi.query(defectSuitesOfThisDefectRequest).getResults();
System.out.println("suites: " + suites);
suites.add(defectSuiteJsonObject);
System.out.println("suites after add: " + suites);
//Update defect: add to defectsutites collection
JsonObject defectUpdate = new JsonObject();
defectUpdate.add("DefectSuites", suites);
UpdateRequest updateDefectRequest = new UpdateRequest(defectRef,defectUpdate);
UpdateResponse updateResponse = restApi.update(updateDefectRequest);
if (updateResponse.wasSuccessful()) {
System.out.println("Successfully updated defect: " + defectJsonObject.get("FormattedID"));
}
else {
String[] updateErrors;
updateErrors = createResponse.getErrors();
System.out.println("Error");
for (int i=0; i<updateErrors.length;i++) {
System.out.println(updateErrors[i]);
}
}
} else {
System.out.println("error");
}
} finally {
restApi.close();
}
}
}
The Defect object has a DefectSuites collection, so you could just query for all defects where DefectSuites contains your specified DefectSuite:
QueryRequest defectsRequest = new QueryRequest("Defect");
defectsRequest.setFetch(new Fetch("FormattedID","Name"));
defectsRequest.setQueryFilter(new QueryFilter("DefectSuites", "contains", defectSuiteRef));
QueryResponse defectsResponse = restApi.query(defectsRequest);
Or, you can come at it from the other way by querying the Defects collection directly on your DefectSuite in your original code above:
JsonObject defectsCollection = defectSuiteJsonObject.getAsJsonObject("Defects");
QueryRequest defectsRequest = new QueryRequest(defectsCollection);
defectSuiteRequest.setFetch(new Fetch("FormattedID","Name"));
QueryResponse defectsResponse = restApi.query(defectsRequest);
I provide a working code in the answer below, as this set of API's is relatively new, and I could not see other end-to-end examples in the web, so may be useful as a reference for anyone wishing to use the new set of API's.
I'm trying to use the new set of published APIs of WSO2 AM 1.10.0. I wrote a sample client, based on an article of Sanjeewa Malalgoda: http://wso2.com/library/articles/2015/11/article-introducing-wso2-api-manager-new-rest-api-for-store-and-publisher-operations
Here is the code, based on that article and fixes some minor errors/typos:
package test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
public class test
{
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
// PHASE 1: REGISTER CLIENT
// ------------------------
String dcrEndpointURL = getKeyManagerURLHttp() +
"client-registration/v0.9/register";
String applicationRequestBody = " {\n" +
" \"callbackUrl\": \"google.sk\",\n" +
" \"clientName\": \"test_11\",\n" +
" \"tokenScope\": \"Production\",\n" +
" \"owner\": \"admin\",\n" +
" \"grantType\": \"password refresh_token\",\n" +
" \"saasApp\": true\n" +
" }";
Map<String, String> dcrRequestHeaders = new HashMap<String, String>();
// This is base 64 encoded basic Auth value for user name admin and password admin.
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(dcrRequestHeaders.get("Authorization"));
dcrRequestHeaders.put("Content-Type", "application/json");
JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
new URL(dcrEndpointURL),
applicationRequestBody,dcrRequestHeaders));
System.out.println(clientRegistrationResponse);
consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
System.out.println(consumerKey);
System.out.println(consumerSecret);
Thread.sleep(2000);
// PHASE 2: REQUEST TOKEN
// ----------------------
String requestBody = "grant_type=password&username=admin&password=admin&scope=API_CREATOR_SCOPE";
URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");
Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
String basicAuthConsumer = consumerKey + ":" + consumerSecret;
byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));
JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
System.out.println(accessTokenGenerationResponse);
//Get access token and refresh token from token API call.
//Now we have access token and refresh token that we can use to invoke API.
JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
String userAccessToken = tokenData.getString("access_token");
String refreshToken = tokenData.getString("refresh_token");
System.out.println("Access token: " + userAccessToken);
System.out.println("Refresh token: " + refreshToken);
// PHASE 3: CALL THE API
// ---------------------
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Bearer " + userAccessToken);
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
The code registers the client and returns access and refresh token successfully.
Here is the response of the token request:
"data":
{
"access_token": "bb5176def22ffbc4a7b12d2fd1ee9733",
"refresh_token": "357926275971df21f9529ebb30ba36d1",
"scope":"default",
"token_type":"Bearer",
"expires_in":2502
}
However, when I send this token in the header of the API query:
{Authorization=Bearer bb5176def22ffbc4a7b12d2fd1ee9733}
I get error code 401/Unauthorized.
Looking at the server log, I get the following:
[2016-02-07 17:38:20,371] ERROR - WebAppAuthenticatorImpl You cannot access API as scope validation failed
[2016-02-07 17:38:20,372] WARN - PhaseInterceptorChain Interceptor for {http://publisher.api.rest.apimgt.carbon.wso2.org/}SubscriptionsApi has thrown exception, unwinding now
org.apache.cxf.interceptor.security.AuthenticationException: Unauthenticated request
at org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.OAuthAuthenticationInterceptor.handleMessage(OAuthAuthenticationInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:217)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:268)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke(CarbonTomcatValve.java:47)
at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:57)
at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:47)
at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1698)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
Some notes
I'm running version 1.10.0, from http://wso2.com/api-management/try-it
WSO2 Published API's that I have on this deployment are all v0.9 (and not v1, as appear in some of the examples)
I tried the token request with both API_CREATOR_SCOPE, API_PUBLISHER_SCOPE. Both fail.
In the response of the token request, it says "scope: default". Not sure if this is ok or not.
The exception says "You cannot access API as scope validation failed", so I guess there is an issue with the scope. But I'm not sure why and how to fix.
Please check roles and scope available in /_system/config/apimgt/applicationdata/tenant-conf.json file. Then request token with scopes mentioned there. Then you will get access token with correct scope. Please note that tokens with default scope cannot use for REST API functionalities.
For basic authentication, change beans.xml of repository\deployment\server\webapps\api#am#publisher#v0.9\WEB-INF to:
<bean id="AuthenticationInterceptor" class="org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.BasicAuthenticationInterceptor" />
And then code is much simplified:
public class test {
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
String dcrEndpointURL = getKeyManagerURLHttp()+"client-registration/v0.9/register";
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
System.out.println(response.getData());
HttpResponse response1 = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/subscriptions",requestHeaders);
System.out.println(response1.getResponseCode());
System.out.println(response1.getResponseMessage());
System.out.println(response1.getData());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
Here is a working example, following Sanjeewa's fix.
package test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
public class test
{
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
// PHASE 1: REGISTER CLIENT
// ------------------------
String dcrEndpointURL = getKeyManagerURLHttp() +
"client-registration/v0.9/register";
String applicationRequestBody = " {\n" +
" \"callbackUrl\": \"google.sk\",\n" +
" \"clientName\": \"test_11\",\n" +
" \"tokenScope\": \"Production\",\n" +
" \"owner\": \"admin\",\n" +
" \"grantType\": \"password refresh_token\",\n" +
" \"saasApp\": true\n" +
" }";
Map<String, String> dcrRequestHeaders = new HashMap<String, String>();
// This is base 64 encoded basic Auth value for user name admin and password admin.
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(dcrRequestHeaders.get("Authorization"));
dcrRequestHeaders.put("Content-Type", "application/json");
JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
new URL(dcrEndpointURL),
applicationRequestBody,dcrRequestHeaders));
System.out.println(clientRegistrationResponse);
consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
System.out.println(consumerKey);
System.out.println(consumerSecret);
Thread.sleep(2000);
// PHASE 2: REQUEST TOKEN
// ----------------------
String requestBody = "grant_type=password&username=admin&password=admin&scope=apim:view_api";
URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");
Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
String basicAuthConsumer = consumerKey + ":" + consumerSecret;
byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));
JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
System.out.println(accessTokenGenerationResponse);
//Get access token and refresh token from token API call.
//Now we have access token and refresh token that we can use to invoke API.
JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
String userAccessToken = tokenData.getString("access_token");
String refreshToken = tokenData.getString("refresh_token");
System.out.println("Access token: " + userAccessToken);
System.out.println("Refresh token: " + refreshToken);
// PHASE 3: CALL THE API
// ---------------------
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Bearer " + userAccessToken);
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
System.out.println(response.getData());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
Result:
200
OK
{"count":1,"next":"","list":[{"name":"employees","context":"/employees","id":"09cef2c8-89f0-405e-97af-225942a52d83","description":null,"version":"1.0.0","provider":"admin","status":"PUBLISHED"}],"previous":""}
I have oAuth 2.0 code that works with other services (such as LinkedIn and Facebook) but niot Google.
The code fails with 'Consumer is not registered'. It certainly is. That is if this error means what I think it means but I do have the following in https://code.google.com/apis/console.
a project,
and a valid CLIENT_ID entry
Client ID: 107***********4ek7fl.apps.googleusercontent.com
Client secret: Q6KbA**********FRbL
Redirect URIs: urn:ietf:wg:oauth:2.0:oob, htp://{localhost}
The failure occurs when the request is first sent to https://accounts.google.com/o/oauth2/auth
No page is displayed asking the user to authenticate, the Google server returns "Consumer is not registered" in the response body.
I had a similar problem. I am using the scribe oauth java library, https://github.com/fernandezpablo85/scribe-java. It's support of Google is only oauth 1.0, so I had to write my own class that extends org.scribe.builder.api.DefaultApi20 instead of org.scribe.builder.api.DefaultApi10a.
basically here you are:
package org.scribe.builder.api;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.scribe.exceptions.OAuthException;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;
/**
* Google OAuth2.0
* Released under the same license as scribe (MIT License)
* #author houman001
* This code borrows from and modifies changes made by #yincrash
* #author yincrash
*
*/
public class Google2Api extends DefaultApi20 {
private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
private static final String SUFFIX_OFFLINE = "&" + OAuthConstants.ACCESS_TYPE + "=" + OAuthConstants.ACCESS_TYPE_OFFLINE
+ "&" + OAuthConstants.APPROVAL_PROMPT + "=" + OAuthConstants.APPROVAL_PROMPT_FORCE;
#Override
public String getAccessTokenEndpoint() {
return "https://accounts.google.com/o/oauth2/token";
}
#Override
public AccessTokenExtractor getAccessTokenExtractor() {
return new AccessTokenExtractor() {
public Token extract(String response) {
Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile("\"access_token\" : \"([^&\"]+)\"").matcher(response);
if (matcher.find())
{
String token = OAuthEncoder.decode(matcher.group(1));
String refreshToken = "";
Matcher refreshMatcher = Pattern.compile("\"refresh_token\" : \"([^&\"]+)\"").matcher(response);
if (refreshMatcher.find())
refreshToken = OAuthEncoder.decode(refreshMatcher.group(1));
Date expiry = null;
Matcher expiryMatcher = Pattern.compile("\"expires_in\" : ([^,&\"]+)").matcher(response);
if (expiryMatcher.find())
{
int lifeTime = Integer.parseInt(OAuthEncoder.decode(expiryMatcher.group(1)));
expiry = new Date(System.currentTimeMillis() + lifeTime * 1000);
}
Token result = new Token(token, refreshToken, expiry, response);
return result;
}
else
{
throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
}
}
};
}
#Override
public String getAuthorizationUrl(OAuthConfig config) {
// Append scope if present
if (config.hasScope()) {
String format = config.isOffline() ? SCOPED_AUTHORIZE_URL + SUFFIX_OFFLINE : SCOPED_AUTHORIZE_URL;
return String.format(format, config.getApiKey(),
OAuthEncoder.encode(config.getCallback()),
OAuthEncoder.encode(config.getScope()));
} else {
String format = config.isOffline() ? AUTHORIZE_URL + SUFFIX_OFFLINE : AUTHORIZE_URL;
return String.format(format, config.getApiKey(),
OAuthEncoder.encode(config.getCallback()));
}
}
#Override
public Verb getAccessTokenVerb() {
return Verb.POST;
}
#Override
public OAuthService createService(OAuthConfig config) {
return new GoogleOAuth2Service(this, config);
}
private static class GoogleOAuth2Service extends OAuth20ServiceImpl {
private DefaultApi20 api;
private OAuthConfig config;
public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
super(api, config);
this.api = api;
this.config = config;
}
#Override
public Token getAccessToken(Token requestToken, Verifier verifier) {
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
switch (api.getAccessTokenVerb()) {
case POST:
request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
// API Secret is optional
if (config.getApiSecret() != null && config.getApiSecret().length() > 0)
request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
if (requestToken == null) {
request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
request.addBodyParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.GRANT_TYPE_AUTHORIZATION_CODE);
} else {
request.addBodyParameter(OAuthConstants.REFRESH_TOKEN, requestToken.getSecret());
request.addBodyParameter(OAuthConstants.GRANT_TYPE, OAuthConstants.GRANT_TYPE_REFRESH_TOKEN);
}
break;
case GET:
default:
request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
// API Secret is optional
if (config.getApiSecret() != null && config.getApiSecret().length() > 0)
request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope());
}
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
}
}
}
from https://raw.githubusercontent.com/codolutions/scribe-java/master/src/main/java/org/scribe/builder/api/Google2Api.java
I'm able to bind complex objects (bs2 in code below) but getting error while doing for String (bs1 in code below) . using Eclipselink 2.4.2. Please see code:
private static void initJAXBContext() {
String bs1 = "<?xml version=\"1.0\"?>\n" +
"<xml-bindings\n" +
" xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence/oxm\"\n" +
" package-name=\"java.lang\" >\n" +
" <xml-schema element-form-default=\"QUALIFIED\" namespace=\"java.lang\">\n" +
" <xml-ns prefix=\"sc\" namespace-uri=\"java.lang\"/>\n" +
" </xml-schema>\n" +
" <java-types>\n" +
" <java-type name=\"java.lang.String\">\n" +
" <xml-root-element/>\n" +
" </java-type>\n" +
" </java-types>\n" +
"</xml-bindings>";
String bs2 = "<?xml version=\"1.0\"?>\n" +
"<xml-bindings\n" +
" xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence/oxm\"\n" +
" package-name=\"test\" >\n" +
" <xml-schema element-form-default=\"QUALIFIED\" namespace=\"test\">\n" +
" <xml-ns prefix=\"sc\" namespace-uri=\"test\"/>\n" +
" </xml-schema>\n" +
" <java-types>\n" +
" <java-type name=\"test.TestService\">\n" +
" <xml-root-element/>\n" +
" </java-type>\n" +
" </java-types>\n" +
"</xml-bindings>";
List<Object> fl = new ArrayList<Object>();
Map<String, Object> properties = new HashMap<String, Object>();
try {
InputStream iStream2 = new ByteArrayInputStream(bs1.getBytes("UTF-8"));
fl.add(iStream2);
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, fl);
System.out.println("before jaxb");
JAXBContext context = (org.eclipse.persistence.jaxb.JAXBContext) JAXBContext.newInstance("test", Class.forName("test.TestService").getClassLoader(), properties);
System.out.println("after jaxb");
} catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
}
Above code works fine for bs2. But gives following exception for bs1:
---------------------------------------------------------------------------------------
javax.xml.bind.JAXBException
- with linked exception:
[java.lang.NullPointerException]
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:915)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:848)
at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:182)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:249)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at GenericTest.initJAXBContext(GenericTest.java:337)
at GenericTest.main(GenericTest.java:366)
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:249)
at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:104)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:912)
... 12 more
---------------------------------------------------------------------------------------
Can you please let me know the issue with binding string bs1.
Thanks in advance,
Vikas
EclipseLink JAXB (MOXy) does not allow you to treat a data type as a domain object. Below is an example of handling a String as a top level object.
import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
public class Example {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Example.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource xml = new StreamSource(new StringReader("<foo>Hello World</foo>"));
JAXBElement<String> unmarshalJAXBElement = unmarshaller.unmarshal(xml, String.class);
String string = unmarshalJAXBElement.getValue();
System.out.println(string);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement<String> marshalJAXBElement = new JAXBElement<String>(new QName("bar"), String.class, string);
marshaller.marshal(marshalJAXBElement, System.out);
}
Output from running above code:
Hello World
<?xml version="1.0" encoding="UTF-8"?>
<bar>Hello World</bar>
}