Cannot Upload File to OneDrive with Java SDK - java

I cannot upload a file to OneDrive using the MS Graph Java SDK, nor can I find any Java-based examples.
I have found a similar (but unanswered) question here: MS Graph Java SDK: how to upload a large file to OneDrive?
However, I've managed to cobble together a bit more code that was shown in the question raised above (based on a .NET-based example), but still without success.
FileSystemInfo fileSystemInfo = new FileSystemInfo();
fileSystemInfo.createdDateTime = new GregorianCalendar();
fileSystemInfo.lastModifiedDateTime = new GregorianCalendar();
DriveItemUploadableProperties properties = new DriveItemUploadableProperties();
properties.name = "test.jpeg";
properties.description = "TEST_DESCRIPTION";
properties.fileSystemInfo = fileSystemInfo;
IDriveItemCreateUploadSessionRequest request = this.graphServiceClient
.me()
.drive()
.root()
.createUploadSession(properties)
.buildRequest();
UploadSession session = request.post();
if(Objects.nonNull(session)) {
int maxSizeChunk = (320 * 1024) * 4;
String macOsPath = "[ADD YOUR VALID FILE PATH]";
File file = new File(macOsPath);
FileInputStream inputStream = new FileInputStream(file);
ChunkedUploadProvider<File> uploadProvider =
new ChunkedUploadProvider(session, this.graphServiceClient,
inputStream, maxSizeChunk, File.class);
IProgressCallback<File> callback = new IProgressCallback<File>() {
#Override
public void progress(long l, long l1) {
log.info("making progress: " + l + ", " + l1);
}
#Override
public void success(File file) {
log.info("Success! " + file.getName());
}
#Override
public void failure(ClientException e) {
log.info("Failure! " + e.getMessage());
}
};
uploadProvider.upload(callback, 0);
}
The error occurs when attempting to post the upload session request:
UploadSession session = request.post();
Rather than returning an upload session, the following error is returned:
{
"error": {
"code": "invalidRequest",
"message": "The request is malformed or incorrect.",
"innerError": {
"request-id": "b9d4026b-0d8f-44b4-9e9e-8d78a0ea5ea3",
"date": "2019-05-30T16:20:11"
}
}
}

I don't fully understand the reason for requiring DriveItemUploadableProperties but you shouldn't be setting any of its properties.
Try using this instead:
UploadSession session = this.graphServiceClient
.me()
.drive()
.root
.itemWithPath("_hamilton.jpg")
.createUploadSession(new DriveItemUploadableProperties())
.buildRequest()
.post();
I personally find the most useful examples are the unit tests in the SDK itself. In this case, you can find this in OneDriveTests.Java.

Related

Volley in Android not attempting to connect

I've been attempting to get Volley to request data from the internet. Code is below. Forgive the verbose code, this was as quick and dirty test just to see if Volley worked. I'll clean it up once I get it working.
public static Option parseJSON(Context context, String stockTicker, String strikePrice, String expiration) {
final String apikey = "XXXX"; **//key removed just for StackOverflow, but it works**
String ticker = "&symbol=";
final String baseURL = "https://api.tdameritrade.com/v1/marketdata/quotes?";
Option option = new Option();
try {
SimpleDateFormat simpleDate = new SimpleDateFormat("MM/dd/yyyy");
SimpleDateFormat simpleDateforRequest = new SimpleDateFormat("MMddyy");
String formattedDate = simpleDateforRequest.format(simpleDate.parse(expiration));
String fullTicker = stockTicker + "_" + formattedDate + "C" + strikePrice;
ticker = ticker + fullTicker;
} catch (ParseException e) {
e.printStackTrace();
}
final String url = baseURL + apikey + ticker;
RequestQueue queue = Volley.newRequestQueue(context);
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
String jsonObject = response.toString();
Log.d("JSONRequestResponse", "Response: " + jsonObject);
}
}, error -> Log.d("JSONRequestResponse", "Error: " + error.toString()));
queue.add(request);
Log.d("JSON", "Request" + request + " URL: " + url);
return option; **//method doesn't create an option yet, but the problem comes well before this.**
}
The problem is that none of the logd within JsonArrayRequest are triggered and the one at the end is just an empty array ("[]"), making me think that Volley isn't attempting to connect.
I've tried using JsonObjectRequest and StringRequest as well
I've already added '<uses-permission android:name="android.permission.INTERNET'/> to the manifest, as well as trying "ACCESS_NETWORK_STATE"
The final URL works. I clicked it for the final logd and it takes me to a JSON page with the right info
The gradle version is 1.2.1, so it should be the most up-to-date
Again, I'm just testing to see if Volley retrieves a JSON, I haven't gotten to the return Object yet. At this point, I have no idea what it can be. Any help is much appreciated
UPDATE*************************************
As expected, it doesn't seem like the app is connecting to the internet. I've used this following method to see if there is a connect and it returns false:
public static boolean isNetworkAvailable() {
Log.d("CheckPoint", "isNetworkAvailable first line");
final boolean[] availability = {false};
new Thread(new Runnable() {
#Override
public void run() {
try {
availability[0] = InetAddress.getByName("www.google.com").isReachable(5000);
} catch (UnknownHostException e) {
Log.d("CheckPoint", "isNetworkAvailable UnknownHost!");
} catch (IOException e) {
Log.d("CheckPoint", "isNetworkAvailable IOException!");
}
}
}).start();
Log.d("CheckPoint", "Availability: " + availability[0]);
return availability[0];
}
You never called
requestQueue.start()
Although I have to say- unless your really need some feature that only Volley gives you, Retrofit is a much easier to use library, and it avoids some problems with Volley (Volley can cause memory issues with large responses or multiple outstanding requests because it needs to hold the entire response as an in memory String, rather than streaming it to a temp file).

Spring Boot file upload issue - Could not store the file error only occur after few days

I have a RESTful API created using Java Spring Boot 2.4.2.
1 of the main issue that I encountered recently is that, the Multipart file upload is working fine but the same code will not work after couple of days. It will work back after restarted the RESTFul JAR application.
The error that been display in Postman:
Could not store the file. Error
The relevant code to this is here:
try {
FileUploadUtil.saveFile(uploadPath, file.getOriginalFilename(), file);
} catch (IOException e) {
throw new RuntimeException("Could not store the file. Error: " + e.getMessage());
}
And the FileUploadUtil class:
public class FileUploadUtil {
public static void saveFile(String uploadDir, String fileName, MultipartFile multipartFile) throws IOException {
Path uploadPath = Paths.get(uploadDir);
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
try (InputStream inputStream = multipartFile.getInputStream()) {
Path filePath = uploadPath.resolve(fileName);
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ioe) {
throw new IOException("Could not save uploaded file: " + fileName, ioe);
}
}
public static File fileFor(String uploadDir, String id) {
return new File(uploadDir, id);
}}
And the main POST API method head that called the first part of the code above is:
#PostMapping(value = "/clients/details/{clientDetailsId}/files/{department}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
#PreAuthorize("hasAuthority('PERSONNEL') or hasAuthority('CUSTODIAN') or hasAuthority('ADMIN')")
public ResponseEntity<ClientDetails> createClientDetailsFiles(#PathVariable("clientDetailsId") long clientDetailsId,
#PathVariable("department") String department,
#RequestPart(value = "FORM_SEC_58", required = false) MultipartFile[] FORM_SEC_58_file,#RequestPart(value = "FORM_SEC_78", required = false) MultipartFile[] FORM_SEC_78_file,
#RequestPart(value = "FORM_SEC_105", required = false) MultipartFile[] FORM_SEC_105_file,
#RequestPart(value = "FORM_SEC_51", required = false) MultipartFile[] FORM_SEC_51_file,
#RequestPart(value = "FORM_SEC_76", required = false) MultipartFile[] FORM_SEC_76_file)
And the application.properties side:
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=90MB
spring.servlet.multipart.max-request-size=90MB
Can anyone advise what is the issue ya?
I had the same issue, it was working file once, but after some time, it stopped working. I am almost certain your issue is this, because, we have the same code and our scenario is the same. The way I figured it out was:
Debugging
I added a statement to print the error to see what was actually going on, what you are currently doing is only taking message of error, not the whole error. So change it to:
try {
FileUploadUtil.saveFile(uploadPath, file.getOriginalFilename(), file);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not store the file. Error: " + e.getMessage());
}
Actual Problem
And the error was FileAlreadyExistsException FileAlreadyExistsException
Basically what that means is that you are trying to upload a file with same name twice.
Solution
To fix this issue you can use different approaches. One of them is to generate UUID for file and store it also in database, to access later.

How to launch a new openstack instance in Java?

I was trying to launch new open-stack instance in Java by referring below URL.
https://help.dreamhost.com/hc/en-us/articles/216456877-How-to-launch-and-delete-OpenStack-instances-using-Java-and-Jclouds
And here is how my createInstance method looks like :-
public void createInstance(String instanceName) {
for (String region : regions) {
ServerApi serverApi = novaApi.getServerApi(region);
System.out.println("server api : " + serverApi.toString());
String imageId = "7d246e9a-dd2a-4342-97f7-32accd0f9c35";
String flavorId = "8041379d-7261-401d-90cf-e2d97184fe94";
/*Launch an instance*/
ServerCreated ser = serverApi.create(instanceName, imageId, flavorId);
Server server = serverApi.get(ser.getId());
while (server.getStatus().value().equals("ACTIVE") == false) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
server = serverApi.get(ser.getId());
}
System.out.println(ser.getId());
}
}
I am getting HttpResponseException but able to get image Id, flavor Id etc.
exception : org.jclouds.http.HttpResponseException: command: POST http://192.168.1.224:8774/v2/e02b6387fa5a4b619bc2ba554661ea99/servers HTTP/1.1 failed with response: HTTP/1.1 400 Bad Request; content: [{"badRequest": {"message": "Multiple possible networks found, use a Network ID to be more specific.", "code": 400}}]
You have to specify the flavor, image and networks to be used to launching an instance. I see you have specified the flavor and image.
However, you also have to specify the networks to be used. Check the answer in the below link
jcloud_create_instance_with_network

How to use Authentication with JIRA REST API in Java

hi im creating a simple tool using java to create,update and delete issues(tickets) in jira. i am using rest api following code is im using to authenticate jira and issue tickets.
public class JiraConnection {
public static URI jiraServerUri = URI.create("http://localhost:8090/jira/rest/api/2/issue/HSP-1/");
public static void main(String args[]) throws IOException {
final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(jiraServerUri,"vinuvish92#gmail.com","vinu1994");
System.out.println("Sending issue creation requests...");
try {
final List<Promise<BasicIssue>> promises = Lists.newArrayList();
final IssueRestClient issueClient = restClient.getIssueClient();
System.out.println("Sending issue creation requests...");
for (int i = 0; i < 100; i++) {
final String summary = "NewIssue#" + i;
final IssueInput newIssue = new IssueInputBuilder("TST", 1L, summary).build();
System.out.println("\tCreating: " + summary);
promises.add(issueClient.createIssue(newIssue));
}
System.out.println("Collecting responses...");
final Iterable<BasicIssue> createdIssues = transform(promises, new Function<Promise<BasicIssue>, BasicIssue>() {
#Override
public BasicIssue apply(Promise<BasicIssue> promise) {
return promise.claim();
}
});
System.out.println("Created issues:\n" + Joiner.on("\n").join(createdIssues));
} finally {
restClient.close();
}
}
}
according this code i couldn't connect to the jira
**following exception i am getting **
please suggest me best solution to do my task
It seems to me that your error is clearly related to url parameter. The incriminated line and the fact that the error message is about not finding the resource are good indications of it.
You don't need to input the whole endpoint since you are using the JiraRestClient. Depending on the method that you call it will resolve the endpoint. Here is an example that works: as you can see I only input the base url

java jira rest client timeout issue

I get java.net.SocketTimeoutException when searching in jira. How can I increase the timeout ?
Code:
JiraRestClientFactory restClientFactory = new AsynchronousJiraRestClientFactory();
SearchResult results = null;
try {
URI uri = new URI(jira_url);
restClient = restClientFactory.createWithBasicHttpAuthentication(uri, jira_username, jira_password);
final SearchRestClient searchClient = restClient.getSearchClient();
String jql = searchClient.getFilter(jira_filterid).get().getJql();
// setting max result to 1000 and start with 0
results = searchClient.searchJql(jql, 500, 0).claim();
System.out.println("Took: " + stopWatch.toString() + " to find " + results.getTotal() + " case in jira filter with id " + jira_filterid);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return results;
The searching should not take so long, i think it is when doing claim().
Exception:
java.lang.RuntimeException: java.net.SocketTimeoutException
at com.google.common.base.Throwables.propagate(Throwables.java:160)
at com.atlassian.httpclient.apache.httpcomponents.DefaultHttpClient$3.apply(DefaultHttpClient.java:256)
at com.atlassian.httpclient.apache.httpcomponents.DefaultHttpClient$3.apply(DefaultHttpClient.java:249)
at com.atlassian.util.concurrent.Promises$Of$2.apply(Promises.java:276)
at com.atlassian.util.concurrent.Promises$Of$2.apply(Promises.java:272)
at com.atlassian.util.concurrent.Promises$2.onFailure(Promises.java:167)
at com.google.common.util.concurrent.Futures$4.run(Futures.java:1172)
at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:297)
at com.google.common.util.concurrent.ExecutionList.executeListener(ExecutionList.java:156)
at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:145)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:202)
at com.google.common.util.concurrent.SettableFuture.setException(SettableFuture.java:68)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$1$2.run(SettableFuturePromiseHttpPromiseAsyncClient.java:59)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable$1.run(SettableFuturePromiseHttpPromiseAsyncClient.java:197)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient.runInContext(SettableFuturePromiseHttpPromiseAsyncClient.java:90)
at com.atlassian.httpclient.apache.httpcomponents.SettableFuturePromiseHttpPromiseAsyncClient$ThreadLocalDelegateRunnable.run(SettableFuturePromiseHttpPromiseAsyncClient.java:192)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.net.SocketTimeoutException
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:279)
at org.apache.http.impl.nio.client.LoggingAsyncRequestExecutor.timeout(LoggingAsyncRequestExecutor.java:128)
at org.apache.http.impl.nio.DefaultHttpClientIODispatch.onTimeout(DefaultHttpClientIODispatch.java:136)
at org.apache.http.impl.nio.DefaultHttpClientIODispatch.onTimeout(DefaultHttpClientIODispatch.java:50)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:169)
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:257)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:494)
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:207)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:284)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604)
... 1 more
I can not Believe i had to got so deep to change it. you can use reflection to achieve it
try (JiraRestClient client = clientFactory.createWithBasicHttpAuthentication(new URI(jira.getUrl()), jira.getUsername(), jira.getPassword())) {
try {
Field f1 = Class.forName("com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClient").getDeclaredField("httpClient");
Field f2 = Class.forName("com.atlassian.jira.rest.client.internal.async.AtlassianHttpClientDecorator").getDeclaredField("httpClient");
Field f3 = Class.forName("com.atlassian.httpclient.apache.httpcomponents.ApacheAsyncHttpClient").getDeclaredField("httpClient");
Field f4 = Class.forName("org.apache.http.impl.client.cache.CachingHttpAsyncClient").getDeclaredField("backend");
Field f5 = Class.forName("org.apache.http.impl.nio.client.InternalHttpAsyncClient").getDeclaredField("defaultConfig");
Field f6 = Class.forName("org.apache.http.client.config.RequestConfig").getDeclaredField("socketTimeout");
f1.setAccessible(true);
f2.setAccessible(true);
f3.setAccessible(true);
f4.setAccessible(true);
f5.setAccessible(true);
f6.setAccessible(true);
Object requestConfig = f5.get(f4.get(f3.get(f2.get(f1.get(client)))));
f6.setInt(requestConfig, 120 * 1000);
f1.setAccessible(false);
f2.setAccessible(false);
f3.setAccessible(false);
f4.setAccessible(false);
f5.setAccessible(false);
f6.setAccessible(false);
} catch (Exception ignore) {
}
// now you can start using it :)
} catch (URISyntaxException | IOException e) {
logger.error("invalid jira server address: " + jira.getUrl(), e);
throw new RuntimeException("can not access jira server");
}
it will buy you 120 seconds of socket time.
one workaround that seams to work is to take 100 result for each iteration and set startAt
results = searchClient.searchJql(jql, 100, 0).claim();
results1 = searchClient.searchJql(jql, 100, 100).claim();
results2 = searchClient.searchJql(jql, 100, 200).claim();
and so on.
Disclaimer: i am using the Groovy programming language, but the syntax is very similar to Java, so you should be able to reuse the code (hint: in Groovy no semi-colons are needed, the return statement is optional, instead of variable declaration i am using def or final only).
I am using the following library versions (gradle style):
compile "com.atlassian.jira:jira-rest-java-client-core:4.0.0"
compile "com.atlassian.fugue:fugue:2.2.1"
Here we have the standard rest client definition:
JiraRestClient getJiraRestClient()
{
// read user specific Jira password settings and build authentification
final inputFile = new File("${System.getProperty('user.home')}/jiraSettings.json")
final authInfo = new JsonSlurper().parseText(inputFile.text)
// setting up the jira client
def restClient = new AsynchronousJiraRestClientFactory()
.createWithBasicHttpAuthentication(
jiraServerUri,
authInfo.jiraUser.toString(),
authInfo.jiraPassword.toString())
restClient
}
I dived into the createWithBasicHttpAuthentication function and extracted and adapted the code (only getClientOptions - I set the socket timeout to 45 seconds, look at HttpClientOptions default settings):
JiraRestClient getJiraRestClient()
{
return new AsynchronousJiraRestClient(jiraServerUri, getHttpClient());
}
HttpClientOptions getClientOptions()
{
def options = new HttpClientOptions();
options.socketTimeout = 45000L;
options
}
DisposableHttpClient getHttpClient()
{
final DefaultHttpClientFactory defaultHttpClientFactory =
new DefaultHttpClientFactory(new AsynchronousHttpClientFactory.NoOpEventPublisher(),
new AsynchronousHttpClientFactory.RestClientApplicationProperties(jiraServerUri),
new ThreadLocalContextManager() {
#Override
public Object getThreadLocalContext() {
return null;
}
#Override
public void setThreadLocalContext(Object context) {}
#Override
public void clearThreadLocalContext() {}
});
final HttpClient httpClient = defaultHttpClientFactory.create(getClientOptions())
return new AtlassianHttpClientDecorator(httpClient, getAuthenticationHandler()) {
#Override
public void destroy() throws Exception {
defaultHttpClientFactory.dispose(httpClient);
}
}
}
BasicHttpAuthenticationHandler getAuthenticationHandler()
{
// read user specific Jira password settings and build authentification
final inputFile = new File("${System.getProperty('user.home')}/jiraSettings.json")
final authInfo = new JsonSlurper().parseText(inputFile.text)
return new BasicHttpAuthenticationHandler(
authInfo.jiraUser.toString(),
authInfo.jiraPassword.toString())
}
The downside is that I might be forced to adapt this code when I switch to a new version of jira-rest-java-client, but I really need this because the timout is just to short, even with heavy use of paging.
java.util.concurrent.Future class has V get(long timeout, TimeUnit unit).
Adding timeout helped me:
String jql = searchClient.getFilter(jira_filterid).get(120, TimeUnit.SECONDS).getJql();

Categories

Resources