Java MicrosoftGraph Sharepoint search file in Other User Drive - java

Hi Guys i need some help, i got a super user in sharepoint and drive,
I need to create a application in java that when a username and filename is passed to it, will go into the users drive and look for the filename passed and return the file-Id for it. i by chance the user has multiple files with the same name i need to return the latest one.
I have tried multiple ways but it does not seem to work
here is a copy of my code
GraphServiceClient graphClient = (GraphServiceClient) GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
IDriveItemRequestBuilder sDriveReq = graphClient.users(userEmail).drive().root();
String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
IDriveItemSearchCollectionRequest searchRequest = sDriveReq.search(encodedFileName).buildRequest();
IDriveItemSearchCollectionPage searchResult = searchRequest.get();
DriveItem fileResult = null;
for (DriveItem driveItem : searchResult.getCurrentPage()) {
fileResult = driveItem;
}

Related

Sharepoint search file and copy from one location to another

String searchFile = "fileName.txt";
GraphServiceClient graphClient = (GraphServiceClient) GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
User me = graphClient.me().buildRequest().get();
ISiteRequestBuilder siteReq = graphClient.sites("sharepointSiteId");
IDriveRequestBuilder driveReq = siteReq.drive();
IDriveItemRequestBuilder driveRootReq = driveReq.root();
IDriveItemRequestBuilder source = driveRootReq.itemWithPath("sourcePath");
IDriveItemRequestBuilder destination = driveRootReq.itemWithPath("destinationPath");
IDriveItemCollectionRequestBuilder childrenReq = source.children();
String sourceId = source.buildRequest().get().id;
String destinationId = destination.buildRequest().get().id;
IDriveItemSearchCollectionPage searchResult = source.search(searchFile).buildRequest().get();
DriveItem fileResult = null;
for(DriveItem driveItem : searchResult.getCurrentPage()){
fileResult = driveItem;
}
if(fileResult!=null){
ItemReference parentReference = new ItemReference();
parentReference.id = destinationId;
driveReq.items(fileResult.id).copy(searchFile, parentReference).buildRequest().post();
}
I have this Java code to search a file on a sharepoint site location and copy it to another one.
It works ok but it has a bug, I cannot seem to be able to limit the search only to the source path and instead the search the whole site for the files with that name, so if I got multiple files with that name in the site it will bring them all in the results and that can mess up my copy.
Any one can help me solve this?
PS. if you have any pointers also to optimise this code they are also welcome.

Running LotusScript Domino Agents as User and get SdtOutput (LotusScript prints) from Java OSGi bundle

I've developed an OSGi bundle on Domino which should execute code in context of a user. There exists a lot of code in LotusScript also which is too much work to rewrite (Web agents). So I'm looking for a solution to run these web agents as user and grab the output (the prints). I've tried a lot but now I'm stuck that I can either run the agent as Agent Signer (result of session.effectiveUserName) and be able to grab the output or run the agent as the user but don't be able to grab the output. But because it's essential that the LotusScript code has to respect the reader fields, it must run as user. And because I need the output from the agent to do the rest in Java, I need a way to grab the StdOut also.
What I have tried so far:
OpenNTF Domino API: I can run agents as user but I can't grab the output (Or I don't know how)
String user = "Effective User/Acme";
TrustedSessionFactory factory = new TrustedSessionFactory(null);
Sessions s = factory.createSession(user);
Database db = .getDatabase(null, "path/db.nsf");
Agent ag = db.getAgent("LotusScript-Web-Agent")
ag.run();
/* How can I grap the prints?? */
Darwino NAPI: I can't run agents as user but I can grab the output (Or I don't know how)
String user = "CN=Effective User Name/O=Acme";
String prints = null;
NSFSession nsfSession = null;
NSFDatabase nsfDb = null;
NSFAgent nsfAg = null;
RunContext runContext = null;
try {
DominoAPI napi = DominoAPI.get();
nsfSession = new NSFSession(napi, user, true, false);
nsfDb = nsfSession.getDatabase(null, "path/db.nsf");
nsfAg = nsfDb.getDesign().getAgent("LotusScript-Web-Agent");
runContext = nsfAg.createRunContext(true);
runContext.redirectOutput(AGENT_REDIR.MEMORY);
runContext.documentContext(nsfNote);
runContext.run(false);
/* How can I run the agent as "Effective User/Acme" and not as agent signer ?? */
prints = runContext.getStdoutBuffer();
} finally {
if (runContext != null)
runContext.free();
if (nsfAg != null)
nsfAg.free();
if (nsfDb != null)
nsfDb.free();
if (nsfSession != null)
nsfSession.free();
}
Domino-JNA: I can't run agents as user but I can grab the output (Or I don't know how)
String prints = NotesGC.runWithAutoGC(() -> {
String user = "Effective User/Acme";
NotesDatabase ndb = new NotesDatabase(null, "path/db.nsf", user);
NotesAgent ag = ndb.getAgent("LotusScript-Web-Agent");
Writer printWriter = new StringWriter();
NotesAgentRunContext narc = new NotesAgentRunContext();
narc.setUsername(user);
narc.setCheckSecurity(true);
narc.setOutputWriter(printWriter);
ag.run(narc);
/* How can I run the agent as "Effective User/Acme" and not as agent signer ?? */
return printWriter.toString();
});
Does anybody know a solution or can give me a hint to solve this situation?

Google drive api to get all children is not working if I dynamically pass fileId to query

I am trying google drive api to search parents of a folder. In search query i have to pass file id dynamically instead of hard coding. I tried below code. but I am getting file not found json response.
here its not taking fileId as value i think its consider as String
if I hardcode the value it is working.
FileList result = service.files().list().setQ("name='testfile' ").execute();
for (com.google.api.services.drive.model.File file : result.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
file.getName(), file.getId());
String fileId =file.getId();
FileList childern = service.files().list().setQ(" + \"file.getId()\" in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
This should help.
String fileid=file.getId()
service.files().list().setQ("'" + fileId + "'" + " in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
Make sure you have valid file.getId()
I know your question states java but the only sample of this working is in C#. Another issue is as far as i know PageStreamer.cs does not have an equivalent in the java client library.
I am hoping that C# and java are close enough that this might give you some ideas of how to get it working in Java. My java knowledge is quote basic but i may be able to help you debug it if you want to try to convert this.
try
{
// Initial validation.
if (service == null)
throw new ArgumentNullException("service");
// Building the initial request.
var request = service.Files.List();
// Applying optional parameters to the request.
request = (FilesResource.ListRequest)SampleHelpers.ApplyOptionalParms(request, optional);
var pageStreamer = new Google.Apis.Requests.PageStreamer<Google.Apis.Drive.v3.Data.File, FilesResource.ListRequest, Google.Apis.Drive.v3.Data.FileList, string>(
(req, token) => request.PageToken = token,
response => response.NextPageToken,
response => response.Files);
var allFiles = new Google.Apis.Drive.v3.Data.FileList();
allFiles.Files = new List<Google.Apis.Drive.v3.Data.File>();
foreach (var result in pageStreamer.Fetch(request))
{
allFiles.Files.Add(result);
}
return allFiles;
}
catch (Exception Ex)
{
throw new Exception("Request Files.List failed.", Ex);
}

Listing public folders

I'm writing a program for importing contacts from an ERP system to Outlook. Different emails will receive different lists of contacts from ERP. The idea here is, in each email I have a public contact folder that can be accessed by a technical user. The technical user can write contacts into this folder. Here is the code for searching the folder:
protected FolderId findFolderId(String folderDisplayName, String userEmail) throws Exception {
Mailbox userMailbox = new Mailbox(userEmail);
FolderId contactRootFolder = new FolderId(WellKnownFolderName.Root, userMailbox);
FolderId result = null;
FolderView view = new FolderView(Integer.MAX_VALUE);
view.setPropertySet(new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName));
view.setTraversal(FolderTraversal.Deep);
FindFoldersResults findFolderResults = this.service.findFolders(contactRootFolder, view);
//find specific folder
for (Folder f : findFolderResults) {
if (folderDisplayName.equals(f.getDisplayName())) {
result = f.getId();
}
}
return result;
}
The service object is created as follows:
this.service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials(userName, passWord);
this.service.setCredentials(credentials);
try {
this.service.setUrl(new URI(URL));
} catch (URISyntaxException e) {
LOGGER.error(e);
}
Where URL is the end point for the Exchange server (for Office 365 it is https://outlook.office365.com/EWS/Exchange.asmx).
The code works with Office 2010, I get the Id from that folder, connect to it and save the contacts. After the migration to Office 365, we can't find the public folder. It can just find a folder with the name "PeoplePublicData". (I don't even know that folder exists.)
Throttling in Office365 means your code will only return the first 1000 folder in the Mailbox so if what your looking for isn't within that result set that would be one reason. I would suggest you get rid of
FolderView view = new FolderView(Integer.MAX_VALUE);
and change it to
FolderView view = new FolderView(1000);
and then page the results https://msdn.microsoft.com/en-us/library/office/dn592093(v=exchg.150).aspx which will allow you to get all the Folder in a Mailbox. Also unless you are looking for something in the Non_IPM_Subtree of the Mailbox start the search with MsgFolderRoot eg
FolderId contactRootFolder = new FolderId(WellKnownFolderName.MsgFolderRoot, userMailbox);
That will reduce the number of folders returned.
Also why don't you use a SearchFilter to search for the folder you are after eg https://msdn.microsoft.com/en-us/library/office/dd633627(v=exchg.80).aspx this would eliminate the need to page the results,

Overriding authentication behavior in jclouds

I'm looking to leverage RackSpace's CloudFiles platform for large object storage (word docs, images, etc). Following some of their guides, I found a useful code snippet, that looks like it should work, but doesn't in my case.
Iterable<Module> modules = ImmutableSet.<Module> of(
new Log4JLoggingModule());
Properties properties = new Properties();
properties.setProperty(LocationConstants.PROPERTY_ZONE, ZONE);
properties.setProperty(LocationConstants.PROPERTY_REGION, "ORD");
CloudFilesClient cloudFilesClient = ContextBuilder.newBuilder(PROVIDER)
.credentials(username, apiKey)
.overrides(properties)
.modules(modules)
.buildApi(CloudFilesClient.class);
The problem is that when this code executes, it tries to log me in the IAD (Virginia) instance of CloudFiles. My organization's goal is to use the ORD (Chicago) instance as primary to be colocated with our cloud and use DFW as a back up environment. The login response results in the IAD instance coming back first, so I'm assuming JClouds is using that. Browsing around, it looks like the ZONE/REGION attributes are ignored for CloudFiles. I was wondering if there is any way to override the code that comes back for authentication to loop through the returned providers and choose which one to login to.
Update:
The accepted answer is mostly good, with some more info available in this snippet:
RestContext<CommonSwiftClient, CommonSwiftAsyncClient> swift = cloudFilesClient.unwrap();
CommonSwiftClient client = swift.getApi();
SwiftObject object = client.newSwiftObject();
object.getInfo().setName(FILENAME + SUFFIX);
object.setPayload("This is my payload."); //input stream.
String id = client.putObject(CONTAINER, object);
System.out.println(id);
SwiftObject obj2 = client.getObject(CONTAINER,FILENAME + SUFFIX);
System.out.println(obj2.getPayload());
We are working on the next version of jclouds (1.7.1) that should include multi-region support for Rackspace Cloud Files and OpenStack Swift. In the meantime you might be able to use this code as a workaround.
private void uploadToRackspaceRegion() {
Iterable<Module> modules = ImmutableSet.<Module> of(new Log4JLoggingModule());
String provider = "swift-keystone"; //Region selection is limited to swift-keystone provider
String identity = "username";
String credential = "password";
String endpoint = "https://identity.api.rackspacecloud.com/v2.0/";
String region = "ORD";
Properties overrides = new Properties();
overrides.setProperty(LocationConstants.PROPERTY_REGION, region);
overrides.setProperty(Constants.PROPERTY_API_VERSION, "2");
BlobStoreContext context = ContextBuilder.newBuilder(provider)
.endpoint(endpoint)
.credentials(identity, credential)
.modules(modules)
.overrides(overrides)
.buildView(BlobStoreContext.class);
RestContext<CommonSwiftClient, CommonSwiftAsyncClient> swift = context.unwrap();
CommonSwiftClient client = swift.getApi();
SwiftObject uploadObject = client.newSwiftObject();
uploadObject.getInfo().setName("test.txt");
uploadObject.setPayload("This is my payload."); //input stream.
String eTag = client.putObject("jclouds", uploadObject);
System.out.println("eTag = " + eTag);
SwiftObject downloadObject = client.getObject("jclouds", "test.txt");
System.out.println("downloadObject = " + downloadObject.getPayload());
context.close();
}
Use swift as you would Cloud Files. Keep in mind that if you need to use Cloud Files CDN stuff, the above won't work for that. Also, know that this way of doing things will eventually be deprecated.

Categories

Resources