I have around 20 githubs that I update some information for with the koshuke GitHub API:
try {
settings = settingsRepository.findById(1).orElseThrow(() -> new RuntimeException("No settings found"));
GitHub gitHub = GitHub.connect(settings.getUsername(), settings.getToken());
GHRepository repo;
try {
repo = gitHub.getRepository(gitHubModel.getUser() + "/" + gitHubModel.getRepo());
} catch (Exception e) {
e.printStackTrace();
throw new GitHubRepositoryException("Couldn't connect to " + gitHubModel.getLink() + ". Check URL.");
}
There is event that loops around them on every 2-3 seconds, takes one of the githubs, updates it and after 2-3 seconds continues to the next one. After certain amount of updates the code stops at:
repo = gitHub.getRepository(gitHubModel.getUser() + "/" + gitHubModel.getRepo());.
I tried debugging and found out that it stops at certain point and it throws 403 Forbidden:
private <T> T parse(Class<T> type, T instance, int timeouts) throws IOException {
InputStreamReader r = null;
int responseCode = -1;
String responseMessage = null;
try {
responseCode = uc.getResponseCode();
responseMessage = uc.getResponseMessage();
if (responseCode == 304) {
return null; // special case handling for 304 unmodified, as the content will be ""
}
if (responseCode == 204 && type!=null && type.isArray()) {
// no content
return type.cast(Array.newInstance(type.getComponentType(),0));
}
r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
String data = IOUtils.toString(r);
if (type!=null)
try {
return setResponseHeaders(MAPPER.readValue(data, type));
} catch (JsonMappingException e) {
throw (IOException)new IOException("Failed to deserialize " +data).initCause(e);
}
if (instance!=null) {
return setResponseHeaders(MAPPER.readerForUpdating(instance).<T>readValue(data));
}
return null;
} catch (FileNotFoundException e) {
// java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in HttpException
// to preserve backward compatibility
throw e;
} catch (IOException e) {
if (e instanceof SocketTimeoutException && timeouts > 0) {
LOGGER.log(INFO, "timed out accessing " + uc.getURL() + "; will try " + timeouts + " more time(s)", e);
return parse(type, instance, timeouts - 1);
}
throw new HttpException(responseCode, responseMessage, uc.getURL(), e);
} finally {
IOUtils.closeQuietly(r);
}
}
Then the exception is consumed and it comes to a point where it calls Thread.sleep and stops there.
Is this because I have exceeded the limit of requests? Somewhere I have read that it is 5000 request a minute and I am not doing that many. Any ideas why is this happening?
Related
I'm trying to detect rooted device on my app before my login process. Regarding to this answer , I decided to use SafetyNet. I edited this code like this:
public class RootedDeviceCheckWithSafetyNetAttestation {
public static AtomicInteger sendSafetyNetRequest(Activity context) {
AtomicInteger rootCheck = new AtomicInteger();
if(GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS) {
Log.e(TAG, "The SafetyNet Attestation API is available");
// TODO(developer): Change the nonce generation to include your own, used once value,
// ideally from your remote server.
String nonceData = "Safety Net Sample: " + System.currentTimeMillis();
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
Random mRandom = new SecureRandom();
byte[] bytes = new byte[24];
mRandom.nextBytes(bytes);
try {
byteStream.write(bytes);
byteStream.write(nonceData.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
byte[] nonce = byteStream.toByteArray();
SafetyNetClient client = SafetyNet.getClient(context);
Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce, MY-API-KEY);
task.addOnSuccessListener(context, attestationResponse -> {
/*
TODO(developer): Forward this result to your server together with
the nonce for verification.
You can also parse the JwsResult locally to confirm that the API
returned a response by checking for an 'error' field first and before
retrying the request with an exponential backoff.
NOTE: Do NOT rely on a local, client-side only check for security, you
must verify the response on a remote server!
*/
String jwsResult = attestationResponse.getJwsResult();
Log.e(TAG, "Success! SafetyNet result:\n" + jwsResult + "\n");
if (jwsResult == null) {
Log.e(TAG, "jwsResult Null");
}
final String[] jwtParts = jwsResult.split("\\.");
if (jwtParts.length == 3) {
String decodedPayload = new String(Base64.decode(jwtParts[1], Base64.DEFAULT));
try {
JSONObject jsonObject = new JSONObject(decodedPayload);
//Toast.makeText(context, "ctsProfileMatch:" + jsonObject.getString("ctsProfileMatch")+","+"basicIntegrity:" + jsonObject.getString("basicIntegrity"), Toast.LENGTH_SHORT).show();
if((jsonObject.getString("ctsProfileMatch").equals("false")) && (jsonObject.getString("basicIntegrity").equals("false"))){
rootCheck.set(4);
}
else{
rootCheck.set(1);
}
} catch (JSONException e) {
e.printStackTrace();
rootCheck.set(2);
}
//Toast.makeText(context, decodedPayload, Toast.LENGTH_SHORT).show();
//Log.e(TAG, "decodedPayload : " + decodedPayload);
}
});
task.addOnFailureListener(context, e -> {
// An error occurred while communicating with the service.
String mResult = null;
rootCheck.set(5);
if (e instanceof ApiException) {
// An error with the Google Play Services API contains some additional details.
ApiException apiException = (ApiException) e;
Log.e(TAG, "Error: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
apiException.getStatusMessage());
Toast.makeText(context, "Error: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
apiException.getStatusMessage(), Toast.LENGTH_LONG).show();
} else {
// A different, unknown type of error occurred.
Log.e(TAG, "ERROR! " + e.getMessage());
Toast.makeText(context, "ERROR! " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
} else {
Log.e(TAG, "Prompt user to update Google Play services.");
rootCheck.set(3);
}
return rootCheck;
}
}
When I try to on emulator or rooted device, I can see that my rootCheck variable becomes 4 as I written in code.
The problem is; in real phones, at first login, my code can detect rooted device too. But if I close the app and kill from background and re-open again, I see that my code gives this toast Error: CANCELLED: null so I see that rootCheck variable 5 which means that jumps to task.addOnFailureListener area in if (e instanceof ApiException). This problem causes on rooted and normal device, doesn't matter.
What is the problem? Can you help me ?
I use zip4j to unzip zip packages which are safed by a password (AES-256). My problem is not, that the code is not working, rather that it doen't throw any error when the password doesn't match with the actual on the .zip.
the .zip has a password with 123 and for zip4j I set the password 123456789. So he is not able to extract all. I expect an Error or any message, that it could not extract. The actual case is, he doesn't extract it but no exception or error message, nothing.
Any Idea how I can check if the extraction was successful?
protected void unpackZip(String destinationPath, String archivePath) throws InterruptedException {
int onChange = 0;
try {
ZipFile zipFile = new ZipFile( archivePath );
zipFile.setRunInThread( true );
if (zipFile.isEncrypted()) {
zipFile.setPassword( "123456789");
}
zipFile.extractAll( destinationPath );
// http://www.lingala.net/zip4j/forum/index.php?topic=68.0
ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
while (progressMonitor.getState() == ProgressMonitor.STATE_BUSY) {
// To get the percentage done
if (onChange != progressMonitor.getPercentDone()) {
onChange = progressMonitor.getPercentDone();
sendWebStatusUiMessage( "Extracted : " + onChange + "% ", "update" );
}
try {
Thread.sleep( 1000 );
} catch (Exception e) {
}
}
} catch (ZipException e) {
e.printStackTrace();
}
}
This answer is a bit late, but just in case it might be useful for anyone:
When running zip4j in thread mode, you have to check for the status of the task execution and exception (if errored), after the while loop.
while (progressMonitor.getState() == ProgressMonitor.STATE_BUSY) {
// To get the percentage done
if (onChange != progressMonitor.getPercentDone()) {
onChange = progressMonitor.getPercentDone();
sendWebStatusUiMessage( "Extracted : " + onChange + "% ", "update" );
}
try {
Thread.sleep( 1000 );
} catch (Exception e) {
}
}
if (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {
System.out.println("Successfully added folder to zip");
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {
System.out.println("Error occurred. Error message: " + progressMonitor.getException().getMessage());
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {
System.out.println("Task cancelled");
}
Here's the logic I used:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
retries = 0;
} catch (Exception ex) { //Note. Please excuse this catch pattern. Its not a problem now.
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return resp;
Number of retries is considering original operation as well. But the problem is that
if I return from try block directly without assigning anything, then SCA (Fortify for me) reports that the variable retries is not read (in success flow), and
if I assign and do as above, then SCA shouts about the immediate
reassignment of value to the retries variable without even reading
it.
Considerations:
The first call should be independent of whatever value we read for
'retries'
Duplicate code should be avoided, and avoiding recursion will be
nice too.
May be a simple thing, but I am not catching it probably. Please suggest.
Why do you not use break instead of set retries to 0? I guess you sets retries after operation execute, because you want to break executing loop:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
break;
} catch (Exception ex) {
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return resp;
Or if you want you can return resp in try catch, and return null if did not execute anything:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
return resp;
} catch (Exception ex) {
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return null;
If I were you, I would consider throw exception instead of returning null.
I have a Problem regarding the Telegram API
Whenever I do a RpcCall, it always give me a TimeoutException except when I do a NonAuth Call.
I can SignIn with a Number already and I set Authenticated to true in my AbsApiState and still can only do NonAuth Calls
Here is my Code:
private void startApi() throws Exception
{
api = new TelegramApi(new MyApiStorage(Moin.config.getProp("useTest").equalsIgnoreCase("true") ? true : false),
new AppInfo(Moin.api_id, "console", "???", "???", "en"),
new ApiCallback()
{
#Override
public void onAuthCancelled(TelegramApi arg0)
{
System.out.println("AuthCancelled");
}
#Override
public void onUpdate(TLAbsUpdates update)
{
System.out.println("Updated | " + update.getClass());
}
#Override
public void onUpdatesInvalidated(TelegramApi arg0)
{
System.out.println("Updatefailed");
}
});
TLConfig config = null;
config = api.doRpcCallNonAuth(new TLRequestHelpGetConfig());
if(config != null)
api.getState().updateSettings(config);
else
throw new Exception("config is null, could not update DC List");
login();
}
private void login() throws IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
TLSentCode code = null;
String defaultNumber = Moin.config.getProp("phoneNumber");
System.out.println("Enter a Phone Number (Default ist " + defaultNumber + "):");
String number = reader.readLine();
if(number.equals(" "))
number = defaultNumber;
System.out.println("Sending to " + number + " ...");
try
{
code = api.doRpcCallNonAuth(new TLRequestAuthSendCode(number, 0, Moin.api_id, Moin.api_hash, "en"));
}
catch (RpcException e)
{
if (e.getErrorCode() == 303)
{
int destDC = 0;
if (e.getErrorTag().startsWith("NETWORK_MIGRATE_"))
{
destDC = Integer.parseInt(e.getErrorTag().substring("NETWORK_MIGRATE_".length()));
}
else if (e.getErrorTag().startsWith("PHONE_MIGRATE_"))
{
destDC = Integer.parseInt(e.getErrorTag().substring("PHONE_MIGRATE_".length()));
}
else if (e.getErrorTag().startsWith("USER_MIGRATE_"))
{
destDC = Integer.parseInt(e.getErrorTag().substring("USER_MIGRATE_".length()));
}
else
{
e.printStackTrace();
}
api.switchToDc(destDC);
code = api.doRpcCallNonAuth(new TLRequestAuthSendCode(number, 0, Moin.api_id, Moin.api_hash, "en"));
}
else
e.printStackTrace();
}
String hash = code.getPhoneCodeHash();
System.out.println("Please Enter the Code:");
String smsCode = reader.readLine();
TLAuthorization auth = api.doRpcCallNonAuth(new TLRequestAuthSignIn(number, hash, smsCode));
api.getState().setAuthenticated(api.getState().getPrimaryDc(), true);
//This is where I get the Error
TLExportedAuthorization test = api.doRpcCall(new TLRequestAuthExportAuthorization(api.getState().getPrimaryDc()));
System.out.println(test.getId());
FileOutputStream stream = new FileOutputStream(Paths.get("").toAbsolutePath().toString() + File.separator + "test.txt");
try
{
stream.write(test.getBytes().getData());
}
finally
{
stream.close();
}
TLState state = api.doRpcCall(new TLRequestUpdatesGetState());
System.out.println(state.getDate() + " | " + state.getPts() + " | " + state.getQts() + " | " + state.getUnreadCount());
TLAbsUser user = auth.getUser();
}
And here the Error:
TelegramApi#1001:Timeout Iteration
TelegramApi#1001:RPC #3: Timeout (14999 ms)
TelegramApi#1001:Timeout Iteration
org.telegram.api.engine.TimeoutException
at org.telegram.api.engine.TelegramApi.doRpcCall(TelegramApi.java:364)
at org.telegram.api.engine.TelegramApi.doRpcCall(TelegramApi.java:309)
at org.telegram.api.engine.TelegramApi.doRpcCall(TelegramApi.java:400)
at org.telegram.api.engine.TelegramApi.doRpcCall(TelegramApi.java:396)
at at.nonon.telegram.telegram.Telegram.login(Telegram.java:165)
at at.nonon.telegram.telegram.Telegram.startApi(Telegram.java:105)
at at.nonon.telegram.telegram.Telegram.<init>(Telegram.java:54)
at at.nonon.telegram.telegram.ApiManager.startNew(ApiManager.java:21)
at at.nonon.telegram.Moin.onApiStart(Moin.java:31)
I took alot of the Code from the telegram-bot (https://github.com/ex3ndr/telegram-bot) but even if I copy paste his Code, it still doesn't work...
Thanks in Advance
this problem happened to me, too. I assume you are on a debian or some other linux box. The problem is Oracle JDK's use of the linux random number generator.
In order to make it work, run your application like this:
java -Djava.security.egd=file:/dev/./urandom -jar foo.jar
... meaning, you have to specify the java.security.egd parameter.
Details can be found here: https://github.com/ex3ndr/telegram-api/issues/9#issuecomment-38175765
and here:
http://www.virtualzone.de/2011/10/javas-securerandomgenerateseed-on-linux.html
It started working for me after I changed the server IP address in MemoryApiState as shown below
public void start(boolean isTest) {
connections = new HashMap<>();
connections.put(1, new ConnectionInfo[]{
new ConnectionInfo(1, 0, isTest ? "149.154.175.10" : "149.154.175.50", 443),
});
}
Your timeout might happen for several reasons - please see my answer to TimeoutException on telegram java client
well this is a strange one.
The first save attampt usually works (1 more try max).
but in a heavy load (many saves in a row) the saved file disappears.
if uncommenting the "Thread.sleep" the error is captured otherwise the validation passes succesfully
public void save(Object key, T objToSave) throws FileNotFoundException, IOException {
IOException ex = null;
for (int i = 0; i < NUM_OF_RETRIES; i++) {
try {
/* saving */
String filePath = getFilePath(key);
OutputStream outStream = getOutStream(filePath);
ObjectOutputStream os = new ObjectOutputStream(outStream);
os.writeObject(objToSave);
os.close();
/* validations warnings etc. */
if (i>0){
logger.warn(objToSave + " saved on attamped " + i);
/* sleep more on each fail */
Thread.sleep(100+i*8);
}
//Thread.sleep(50);
File doneFile = new File(filePath);
if (! (doneFile.exists())){
logger.error("got here but file was not witten to disk ! id was" + key);
throw new IOException();
}
logger.info("6. start persist " + key + " path=" + new File(filePath).getAbsolutePath() + " exists="+doneFile.exists());
return;
} catch (IOException e) {
logger.error(objToSave + " failed on attamped " + i);
ex = e;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
throw ex;
}
It is not a java writers issue.
I was not using threads explicitly but in my test I was deleting the folder i was saving to using: Runtime.getRuntime("rm -rf saver_directory");
I found out the hard way that it is asynchronous and the exact delete and create time was changing in mili-seconds.
so the solution was adding "sleep" after the delete.
the correct answer would be using java for the delete and not making a shortcuts ;)
Thank you all.