I am trying to fetch campaign,ad level information from Facebook Using Graph API.
Campaign level information is getting with zero error for all accounts.
But for the Ad Level info, I am not getting the entire data. The API returns only 50. Remaining ads are getting with an exception called "Internal Server Error".
I've been getting this problem all day for one particular account. Every other Account works fine.
Below is the HTTP response:
response = (okhttp3.Response) Response{protocol=http/1.1, code=500, message=Internal Server Error,
url=https://graph.facebook.com/v3.3/act_fbAccountId/ads?access_token=myAccessToken&fields=%5B%22account_id%22%2C%22campaign_id%22%2C%22adset_id%22%2C%22id%22%2C%22bid_amount%22%2C%22name%22%2C%22status%22%2C%22preview_shareable_link%22%5D&limit=25&after=QVFIUkFzZAVdONXEwMXc5NjlOWURwczRQN0V3QW12NndRa0I4ZAUxsSjNkZA0FTRHR1U1dnaTQ5MTh2QnJ3bzNwWkNPd21jbC1tbjRmZAF81WVBsc0txaERCMHVn}
Below is the code
public List facebookAdsSynchThroughJson(String accessTokens, Long advertAccId, Properties googleStructureProperties, byte isOnScheduler, String appSecret) {
this.access_tokens = accessTokens;
this.appSecret = appSecret;
APIContext context = new APIContext(accessTokens, appSecret).enableDebug(true);
List<FacebookAdsStructure> adsList = new ArrayList<>();
String ads = "";
JSONObject advertIdObj = null;
JSONArray dataList = null;
ObjectMapper mapper = null;
boolean cond = true;
boolean success = false;
int limitValue = 100;
try {
while (cond) {
try {
AdAccount adAccount = new AdAccount(advertAccId, context).get().execute();
List adsFields = new ArrayList();
adsFields.add("account_id");
adsFields.add("campaign_id");
adsFields.add("adset_id");
adsFields.add("id");
adsFields.add("bid_amount");
adsFields.add("name");
adsFields.add("status");
adsFields.add("preview_shareable_link");
Map<String, Object> adsmap = new HashMap<>();
adsmap.put("fields", adsFields);
adsmap.put("limit", limitValue);
ads = adAccount.getAds().setParams(adsmap).execute().getRawResponseAsJsonObject().toString();
} catch (APIException ex) {
LOGGER.info("Exception thrown when fetching ads for Account Id: " + advertAccId + " with limit value: " + limitValue);
LOGGER.error(ex);
if (limitValue > 6) {
cond = true;
limitValue = limitValue / 2;
} else {
cond = false;
success = false;
break;
}
}
if (!ads.isEmpty()) {
cond = false;
success = true;
}
}
if (success) {
advertIdObj = new JSONObject(ads);
dataList = advertIdObj.getJSONArray("data");
mapper = new ObjectMapper();
adsList = mapper.readValue(dataList.toString(), new TypeReference<List<FacebookAdsStructure>>() {
});
JsonObject obj;
JsonParser parser = new JsonParser();
JsonElement result = parser.parse(ads);
obj = result.getAsJsonObject();
int maxTries = 1;
if (obj.has("data") && maxTries <= 5) {
while (obj.has("paging") && maxTries <= 5) {
JsonObject paging = obj.get("paging").getAsJsonObject();
if (paging.has("cursors")) {
JsonObject cursors = paging.get("cursors").getAsJsonObject();
String before = cursors.has("before") ? cursors.get("before").getAsString() : null;
String after = cursors.has("after") ? cursors.get("after").getAsString() : null;
}
String previous = paging.has("previous") ? paging.get("previous").getAsString() : null;
String next = paging.has("next") ? paging.get("next").getAsString() : "empty";
if (!next.equalsIgnoreCase("empty")) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.build();
Request request1 = new Request.Builder().url(next).get().build();
Response response = client.newCall(request1).execute();
if (response.isSuccessful()) {
maxTries = 1;
ads = response.body().string();
advertIdObj = new JSONObject(ads);
dataList = advertIdObj.getJSONArray("data");
mapper = new ObjectMapper();
List<FacebookAdsStructure> adsLists = new ArrayList<>();
adsLists = mapper.readValue(dataList.toString(), new TypeReference<List<FacebookAdsStructure>>() {
});
adsList.addAll(adsLists);
LOGGER.info("Fetched the Ad Structure.." + adsList.size());
parser = new JsonParser();
result = parser.parse(ads);
obj = result.getAsJsonObject();
} else {
LOGGER.info("Exception in response when fetching ads for Account Id: " + advertAccId + " , error response message: " + response.message() + " and with limit value: " + limitValue);
maxTries++;
if (maxTries >= 6) {
break;
}
try {
LOGGER.info("Thread Sleeping For 2 Minutes - Started for fb se_account_id " + advertAccId + " and maxTries = " + maxTries);
Thread.sleep(120000);
LOGGER.info("Thread Sleeping For 2 Minutes - Completed for fb se_account_id " + advertAccId + " and maxTries = " + maxTries);
} catch (InterruptedException ex) {
Logger.getLogger(FacebookAccountStructureSyncThroughJson.class.getName()).log(Level.SEVERE, null, ex);
}
}
} else {
obj = new JsonObject();
}
}
}
}
} catch (JsonSyntaxException | IOException | JSONException ex) {
LOGGER.error(ex);
}
return adsList;
}
If anybody knows anything about this issue, please help me.
Related
I am using WordPress rest API to fetch data and I am only fetching 10 posts at a time using volley.
API Link
When I request API in the browser it gives me a result under 6-7 seconds...
But my app takes more than 15 sec to show that 10 posts.
Sometimes it takes more than 1 minute to show the data.
I even added a parameter to get only 2 posts per page. But the response time is the same.
I am searching and modifying code from 2 days but can't get rid of it.
Here is the code:-
private void jsonrequest(int pageNo) {
JSON_URL = "https://jamuitoday.com/wp-json/wp/v2/posts?_embed&page=" + pageNo;
JsonArrayRequest request = new JsonArrayRequest(JSON_URL, response -> {
JSONObject jsonObject;
for (int i = 0; i < response.length(); i++) {
try {
isLoading = true;
isNewsLoaded = false;
jsonObject = response.getJSONObject(i);
News news = new News();
//Get News Link
String link = jsonObject.getString("link");
news.setLink(link);
//Set Date
String date = jsonObject.getString("date");
String d = date.substring(0, 10);
int time = Integer.parseInt(date.substring(11, 13));
if (time > 12) {
String ti = date.substring(13, 16);
String dt = d + " " + (time - 12) + ti + " PM";
news.setdate(dt);
} else {
String ti = date.substring(11, 16);
String dt = d + " " + ti + " AM";
news.setdate(dt);
}
//Set Title
JSONObject title = jsonObject.getJSONObject("title");
String titleren = title.getString("rendered");
news.setName(titleren);
//Set Description
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
JSONObject desc = jsonObject.getJSONObject("content");
String descSub = desc.getString("rendered");
news.setDescription(String.valueOf(Html.fromHtml((descSub))));
news.setAdImgUrl(descSub);
// Set Image
JSONObject img = new JSONObject(jsonObject.getString("_embedded"));
JSONArray ttt = img.getJSONArray("wp:featuredmedia");
String s = "";
for (int t = 0; t < ttt.length(); t++) {
JSONObject obj = ttt.getJSONObject(t);
s = obj.getString("source_url");
}
news.setImage_url(s);
listNews.add(news);
} catch (JSONException e) {
e.printStackTrace();
}
}
setuprecyclerview(listNews);
isLoading = false;
isNewsLoaded = true;
pageNumber += 1;
if (recyclerView.getLayoutManager() != null) {
recyclerView.getLayoutManager().scrollToPosition(currentListPosition);
}
if (shimmerFrameLayout.isShimmerVisible()) {
shimmerFrameLayout.stopShimmer();
shimmerFrameLayout.setVisibility(View.GONE);
}
if (swipyRefreshLayout.isRefreshing()) {
swipyRefreshLayout.setRefreshing(false);
}
}, error -> {
});
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(request);
}
Any hack that can speed it up?
I'll implement SQLite to store data and show at app startup. So, the user can't feel the load time.
Recently, I review the kafka code and test. I found a strange case:
I print the bytebuffer on the entry of SocketServer processCompletedReceives, as well as print the value on the point of Log sotre as follows:
the entry of SocketServer
private def processCompletedReceives() {
selector.completedReceives.asScala.foreach { receive =>
try {
openOrClosingChannel(receive.source) match {
case Some(channel) =>
val header = RequestHeader.parse(receive.payload)
val connectionId = receive.source
val context = new RequestContext(header, connectionId, channel.socketAddress,
channel.principal, listenerName, securityProtocol)
val req = new RequestChannel.Request(processor = id, context = context,
startTimeNanos = time.nanoseconds, memoryPool, receive.payload, requestChannel.metrics)
if(header.apiKey() == ApiKeys.PRODUCE){
LogHelper.log("produce request: %v" + java.util.Arrays.toString(receive.payload.array()))
}
...
the point of Log
validRecords.records().asScala.foreach { record =>
LogHelper.log("buffer info: value " + java.util.Arrays.toString(record.value().array()))
}
but, the result of print is different. and record.value() is not what I passed in client value like this:
public void run() {
int messageNo = 1;
while (true) {
String messageStr = "Message_" + messageNo;
long startTime = System.currentTimeMillis();
if (isAsync) { // Send asynchronously
producer.send(new ProducerRecord<>(topic,
messageNo,
messageStr), new DemoCallBack(startTime, messageNo, messageStr));
} else { // Send synchronously
try {
producer.send(new ProducerRecord<>(topic,
messageNo,
messageStr)).get();
System.out.println("Sent message: (" + messageNo + ", " + messageStr + ")");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
++messageNo;
}
}
the print result is not the not String messageStr = "Message_" + messageNo;
so what happend in the case.
done. I write the code as follows:
public class KVExtractor {
private static final Logger logger = LoggerFactory.getLogger(KVExtractor.class);
public static Map.Entry<byte[], byte[]> extract(Record record) {
if (record.hasKey() && record.hasValue()) {
byte[] key = new byte[record.key().limit()];
record.key().get(key);
byte[] value = new byte[record.value().limit()];
record.value().get(value);
System.out.println("key : " + new String(key) + " value: " + new String(value));
return new AbstractMap.SimpleEntry<byte[], byte[]>(key, value);
}else if(record.hasValue()){
// illegal impl
byte[] data = new byte[record.value().limit()];
record.value().get(data);
System.out.println("no key but with value : " + new String(data));
}
return null;
}
}
I'm trying to write a program that uses Imgur's API to download images based on an account name.
private volatile int threadCount;
private volatile double totalFileSize;
private volatile List<String> albums = new ArrayList<>();
private volatile Map<JSONObject, String> images = new HashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(100, (Runnable r) -> {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
});
private void downloadAlbums(List<String> albums) {
threadCount = 0;
albums.forEach((albumHash) -> {
if (hasRemainingRequests()) {
incThreadCount();
executorService.execute(() -> {
try {
String responseString;
String dirTitle;
String albumUrl = URL_ALBUM + albumHash;
String query = String.format("client_id=%s", URLEncoder.encode(CLIENT_ID, CHARSET));
URLConnection connection = new URL(albumUrl + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", CHARSET);
InputStream response = connection.getInputStream();
try (Scanner scanner = new Scanner(response)) {
responseString = scanner.useDelimiter("\\A").next();
JSONObject obj = new JSONObject(responseString).getJSONObject("data");
dirTitle = obj.getString("title");
String temp = "";
// Get save path from a TextField somewhere else on the GUI
ObservableList<Node> nodes = primaryStage.getScene().getRoot().getChildrenUnmodifiable();
for (Node node : nodes) {
if (node instanceof VBox) {
ObservableList<Node> vNodes = ((VBox) node).getChildrenUnmodifiable();
for (Node vNode : vNodes) {
if (vNode instanceof DestinationBrowser) {
temp = ((DestinationBrowser) vNode).getDestination().trim();
}
}
}
}
final String path = temp + "\\" + formatPath(accountName) + "\\" + formatPath(dirTitle);
JSONArray arr = obj.getJSONArray("images");
arr.forEach((jsonObject) -> {
totalFileSize += ((JSONObject) jsonObject).getDouble("size");
images.put((JSONObject) jsonObject, path);
});
}
} catch (IOException ex) {
//
} catch (Exception ex) {
//
} finally {
decThreadCount();
if (threadCount == 0) {
Platform.runLater(() -> {
DecimalFormat df = new DecimalFormat("#.#");
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);// 714833218
alert.setHeaderText("Found " + images.size() + " images (" + (totalFileSize < 1000000000 ? df.format(totalFileSize / 1000000) + " MB)" : df.format(totalFileSize / 1000000000) + " GB)"));
alert.setContentText("Proceed with download and save images?");
Optional<ButtonType> alertResponse = alert.showAndWait();
if (alertResponse.get() == ButtonType.OK) {
progressBar.setTotalWork(images.size());
executorService.execute(() -> {
for (JSONObject obj : images.keySet()) {
(new File(images.get(obj))).mkdirs();
downloadImage(obj, images.get(obj));
}
});
}
});
}
}
});
}
});
}
albums is a List of codes that are required to send a GET request to Imgur in order to receive that album's images. The data returned is then used in another method which downloads the images themselves.
Now, all of this works fine, but when the program is making all the GET requests the JavaFX thread hangs (GUI becomes unresponsive). And after all the GET requests have been executed, the JavaFX thread stops hanging and the alert shows up with the correct information.
I just don't understand why the GUI becomes unresponsive when I'm not (I believe I'm not) blocking it's thread and I'm using an ExecutorService to do all the network requests.
I'm trying to modify the TestSets property of a TestCase.
JsonArray newTestSets = new JsonArray();
... add values as needed ( in the simplest case I'm clearing the property )
JsonObject updates = new JsonObject();
updates.add("TestSets", newTestSets);
I create the updateRequest like I do for all other updates
UpdateRequest updateRequest = new UpdateRequest(ref, updates)
I don't get any error but nothing has changed. The TestCase is still in several TestSets
What am I missing?
I verified that it works to update TestSets collection on a TestCase. See this github repo.
public class UpdateTestSetsOnTestCase {
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "https://rally1.rallydev.com";
String apiKey = "_abc123";
String workspaceRef = "/workspace/12352608129";
String applicationName = "RestExample_updateTestSetsOnTC";
RallyRestApi restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
try {
String setID = "TS24";
String testid = "TC3";
QueryRequest tsRequest = new QueryRequest("TestSet");
tsRequest.setWorkspace(workspaceRef);
tsRequest.setQueryFilter(new QueryFilter("FormattedID", "=", setID));
QueryResponse tsQueryResponse = restApi.query(tsRequest);
if(tsQueryResponse.getTotalResultCount() == 0){
System.out.println("Cannot find tag: " + setID);
return;
}
JsonObject tsJsonObject = tsQueryResponse.getResults().get(0).getAsJsonObject();
String tsRef = tsJsonObject.get("_ref").getAsString();
System.out.println(tsRef);
QueryRequest testCaseRequest = new QueryRequest("TestCase");
testCaseRequest.setWorkspace(workspaceRef);
testCaseRequest.setFetch(new Fetch("FormattedID", "Name", "TestSets"));
testCaseRequest.setQueryFilter(new QueryFilter("FormattedID", "=", testid));
QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);;
if (testCaseQueryResponse.getTotalResultCount() == 0) {
System.out.println("Cannot find test case : " + testid);
return;
}
JsonObject testCaseJsonObject = testCaseQueryResponse.getResults().get(0).getAsJsonObject();
String testCaseRef = testCaseJsonObject.get("_ref").getAsString();
System.out.println(testCaseRef);
int numberOfTestSets = testCaseJsonObject.getAsJsonObject("TestSets").get("Count").getAsInt();
System.out.println(numberOfTestSets + " testset(s) on " + testid);
QueryRequest testsetCollectionRequest = new QueryRequest(testCaseJsonObject.getAsJsonObject("TestSets"));
testsetCollectionRequest.setFetch(new Fetch("FormattedID"));
JsonArray testsets = restApi.query(testsetCollectionRequest).getResults();
for (int j=0;j<numberOfTestSets;j++){
System.out.println("FormattedID: " + testsets.get(j).getAsJsonObject().get("FormattedID"));
}
testsets.add(tsJsonObject);
JsonObject testCaseUpdate = new JsonObject();
testCaseUpdate.add("TestSets", testsets);
UpdateRequest updateTestCaseRequest = new UpdateRequest(testCaseRef,testCaseUpdate);
UpdateResponse updateTestCaseResponse = restApi.update(updateTestCaseRequest);
if (updateTestCaseResponse.wasSuccessful()) {
QueryRequest testsetCollectionRequest2 = new QueryRequest(testCaseJsonObject.getAsJsonObject("TestSets"));
testsetCollectionRequest2.setFetch(new Fetch("FormattedID"));
JsonArray testsetsAfterUpdate = restApi.query(testsetCollectionRequest2).getResults();
int numberOfTestSetsAfterUpdate = restApi.query(testsetCollectionRequest2).getResults().size();
System.out.println("Successfully updated : " + testid + " TestSets after update: " + numberOfTestSetsAfterUpdate);
for (int j=0;j<numberOfTestSetsAfterUpdate;j++){
System.out.println("FormattedID: " + testsetsAfterUpdate.get(j).getAsJsonObject().get("FormattedID"));
}
}
} finally {
restApi.close();
}
}
}
I am having trouble in running my Android app. It is a simple activity meant to get data from a remote database via HTTP.
I am getting these two errors in log cat:
Error parsing to json on getJarrayFromString();
org.json.JSONException: Value Database of type java.lang.String cannot
be converted to JSONArray.
And:
Error at fillproductlist(): java.lang.NullPointerException
I am not very good at Java/Android and this is first time I am asking this question here. I am unable to understand what layer of my app the problem might be in (my Java code, PHP, or database code)?
Code snapshot:
private void fillProductList() {
if (utils.isInternet()
&& CustomHttpClient.isAddressOk(Utils.LINK_PRODUCTS)) {
final int from = bid.size();
final int nr = 5;
long sqliteSize = db.size(mySqlDatabase.TABLE_BOOKS);
if (from == 0) {
// we add the post variables and values for the request
postParameters.add(new BasicNameValuePair("from", String
.valueOf(0).toString()));
postParameters.add(new BasicNameValuePair("nr", String.valueOf(
nr).toString()));
} else {
postParameters.add(new BasicNameValuePair("from", String
.valueOf(from).toString()));
postParameters.add(new BasicNameValuePair("nr", String.valueOf(
nr).toString()));
}
postParameters.add(new BasicNameValuePair("title", titleSearch));
postParameters.add(new BasicNameValuePair("code", codeSearch));
postParameters.add(new BasicNameValuePair("module", moduleSearch));
if (sortOrder != null)
postParameters.add(new BasicNameValuePair("order", sortOrder));
if (sortType != null)
postParameters.add(new BasicNameValuePair("by", sortType));
task = new RequestTask("books", postParameters);
task.setOnTaskCompleted(new OnTaskCompletedListener() {
public void onTaskStarted() {
if (!rlLoading.isShown()) {
rlLoading.startAnimation(fadeIn());
rlLoading.setVisibility(View.VISIBLE);
}
IS_PRODUCTS_TASK = true;
}
public void onTaskCompleted(String result) {
try {
if (result != "") {
// Enter the remote php link
// we convert the response into json array
jarray = utils.getJarrayFromString(result);
int mysqlSize = (jarray.getJSONObject(0)
.getInt("numRows"));
Log.i(DEBUG, "From " + from + " to " + mysqlSize);
if (from <= mysqlSize) {
int rows;
// we check to see if there is 0
if (jarray.length() > 0) {
Log.i(DEBUG,
"From "
+ from
+ " to "
+ Math.floor(mysqlSize / nr)
* nr);
if (from + 5 <= Math.floor(mysqlSize / nr)
* nr) {
rows = jarray.length();
} else {
rows = mysqlSize % nr + 1;
Utils.IS_ENDED_PRODUCT_LIST = true;
}
ArrayList<String> list = new ArrayList<String>();
for (int i = 1; i < rows; i++) {
JSONObject row = jarray
.getJSONObject(i);
bid.add(row.getInt("bid"));
bTitle.add(row.getString("bTitle"));
bCode.add(row.getString("bCode"));
bPrice.add(row.getString("bPrice")
+ "£");
bDescription.add(row
.getString("bDescription"));
bModule.add(row.getString("bModule"));
bImage.add(Utils.PATH
+ row.getString("bImage"));
list.add(row.getString("bImage"));
// we check if this id already exists in the db, if it doesn't exists w create new one
if (!db.hasIDbooks(row.getInt("bid")))
db.createRowOnBooks(
row.getInt("bid"),
row.getString("bTitle"),
row.getString("bCode"),
row.getString("bPrice"),
row.getString("bDescription"),
row.getString("bModule"),
Utils.PATH
+ row.getString("bImage"),
row.getString("bSpecialOffer"),
row.getInt("bSpecialDiscount"),
row.getString("bDateAdded"));
Log.i(DEBUG,
row.getString("bDescription"));
}
new DownloadImages(list, bAdapter)
.execute();
}
}
postParameters.removeAll(postParameters);
} else {
Utils.IS_ENDED_PRODUCT_LIST = true;
if (rlLoading.isShown()) {
rlLoading.startAnimation(fadeOut());
rlLoading.setVisibility(View.INVISIBLE);
}
}
} catch (Exception e) {
Log.e(DEBUG,
"Error at fillProductList(): " + e.toString());
}
}
});
task.execute();
} else {
// if we are not connected on internet or somehow the link would not work, then we will take the rows stored in sqlite db
if (db.size(mySqlDatabase.TABLE_BOOKS) > 0) {
Cursor cursor = db.getBookssRows(mySqlDatabase.TABLE_BOOKS);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
bid.add(cursor.getInt(cursor
.getColumnIndex(mySqlDatabase.KEY_BID)));
bTitle.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BTITLE)));
bCode.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BCODE)));
bPrice.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BPRICE)) + "£");
bDescription.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BDESCRIPTION)));
bModule.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BMODULE)));
bImage.add(cursor.getString(cursor
.getColumnIndex(mySqlDatabase.KEY_BIMAGE)));
cursor.moveToNext();
}
bAdapter.notifyDataSetChanged();
Utils.IS_ENDED_PRODUCT_LIST = true;
}
}
}
In the OnTaskCompleted before
jarray = utils.getJarrayFromString(result);
add a log entry with
Log.i(DEBUG,result);
I am suspecting that you are getting a null value as result
if(result!="")
does not ensure a valid value.
Cheers