Unable to access SPOOneDriveForBusinessFileActivity REST API call - c#

I'm using Microsoft's o365 REST API Client library (https://github.com/Microsoft/o365rwsclient) and have been able to get many of the API calls to work, but am not having any luck with "SPOOneDriveForBusinessFileActivity". Also, I don't see it advertised in the o365 web service atom feed at https://reports.office365.com/ecp/reportingwebservice/reporting.svc
Here is a description of what the events should return : https://support.office.com/en-gb/article/Understanding-the-User-activity-logs-report-80d0b3b1-1ee3-4777-8c68-6c0dedf1f980
Looking at the source code in https://github.com/Microsoft/o365rwsclient/blob/master/TenantReport/SPOOneDriveForBusinessFileActivity.cs it appears to be a valid function, but when utilizing the o365rwsclient library from a c# application (below) I get a 404 error (URL not found).
Any ideas what's going on? Is this report implemented (Powershell cmdlet or direct REST call would also be acceptable)- and if so, how can I access it?
using Microsoft.Office365.ReportingWebServiceClient;
using System;
namespace O365ReportingDataExport
{
internal class Program
{
private static void Main(string[] args)
{
ReportingContext context = new ReportingContext();
//If you enter invalid authentication information, Visual Studio will throw an exception.
context.UserName = #"PUT YOUR OFFICE 365 USER EMAIL ADDRESS HERE";
context.Password = #"PUT YOUR OFFICE 365 USER PASSWORD HERE";
//FromDateTime & ToDateTime are optional, default value is DateTime.MinValue if not specified
context.FromDateTime = DateTime.MinValue;
context.ToDateTime = DateTime.MinValue;
context.SetLogger(new CustomConsoleLogger());
IReportVisitor visitor = new CustomConsoleReportVisitor();
ReportingStream stream1 = new ReportingStream(context, "SPOOneDriveForBusinessFileActivity", "stream1");
//Calls VisitReport
stream1.RetrieveData(visitor);
Console.WriteLine("Press Any Key...");
Console.ReadKey();
}
private class CustomConsoleLogger : ITraceLogger
{
public void LogError(string message)
{
Console.WriteLine(message);
}
public void LogInformation(string message)
{
Console.WriteLine(message);
}
}
private class CustomConsoleReportVisitor : IReportVisitor
{
public override void VisitBatchReport()
{
foreach (ReportObject report in this.reportObjectList)
{
VisitReport(report);
}
}
public override void VisitReport(ReportObject record)
{
Console.WriteLine("Record: " + record.Date.ToString());
}
}
}
}

After talking to Microsoft's O365 support team, it appears that being able to see file activity in OneDrive for Business is a feature that is still in internal testing (hence being able to see it in their REST API's) that has not been deployed yet.

Related

ExcelDNA RTD with SignalR

I'm trying to hook up ExcelDNA RTD with a ASP.NET SignalR server.
Whenever there is a change on the server a message get pushed to the connected clients, and my ExcelDna add-in is getting the new messages but the registered function is not updated.
My RTD server:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
using ExcelDna.Integration;
using ExcelDna.Integration.Rtd;
namespace DMT.Excel.AddIn
{
[ComVisible(true)]
public class SignalRServer : ExcelRtdServer
{
private HubConnection _connection;
private List<Topic> _topics = new List<Topic>();
public TradesRtdServer()
{
_connection = new HubConnectionBuilder()
.WithUrl("http://localhost:5000/api/test/hub")
.WithAutomaticReconnect()
.Build();
_connection.On<object>("Test", m =>
{
foreach (Topic topic in _topics)
{
topic.UpdateValue(m);
}
});
Task.Run(() => _connection.StartAsync());
}
protected override bool ServerStart()
{
DmtAddIn.Logger.Information("ServerStart");
return true;
}
protected override void ServerTerminate()
{
DmtAddIn.Logger.Information("ServerTerminate");
}
protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
{
DmtAddIn.Logger.Information("ConnectData: {0} - {{{1}}}", topic.TopicId, string.Join(", ", topicInfo));
_topics.Add(topic);
return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);
}
protected override void DisconnectData(Topic topic)
{
_topics.Remove(topic);
DmtAddIn.Logger.Information("DisconnectData: {0}", topic.TopicId);
}
}
}
My function
[ExcelFunction(Name = "SignalR.Test.RTD")]
public static object GetSignalRMessages()
{
return XlCall.RTD("Excel.AddIn.Trading.SignalRServer", null, "Test");
}
When I debug I can see topic.UpdateValue(m); is being hit whenever a message is pushed from the server but not GetSignalRMessages
Am I missing anything to propagate the topic change to the function?
Thank you!
Joseph
I managed to solve this by sending a string from the SignalR server, then deserialize it on the client side
The ExcelRtdServer checks whether the value passed into UpdateValue is different to the previous value. You might be passing either the same value every time, or some value that is interpreted to an Excel data type as the same (e.g. some object type that is converted to the same string every time).
You might be better off building this through the IObservable or Rx abstractions, that are a bit higher-level than the ExcelRtdServer. See the samples here https://github.com/Excel-DNA/Samples/tree/master/RtdClocks
Maybe something like this project which combines Rx and SignalR: https://github.com/jwooley/SignalrRxSamples

Signal R in Web Api

I have Web Api which serves to CRUD Posts from Web App, Android App and Desktop.
I want to add SignalR to the Web Api, every time when Action Create in Controller gets called I want to notify all users that Post is created.
Problem is, I can't find any implementation in only Web Api, all implementations are in Web App with Web Api or something like that. I read all MSDN documentation about it. I'm strugling for 3-4 days now.
I managed to get to the point where I implemented SignalR, and my server isn't created any signalr/hubs file that I need to call from Web App script. It's only created when I run app locally - if I publish it on Azure that file isn't created.
Anyone have concrete steps for Implementation only in Web Api?
I tried this blog, it has Web Api stuff but have js in project and local html added. It's not standalone REST api.
This is not about not creating signalr/hubs file. It's about creating standalone Web Api with SignalR.
I have startup:
public void Configuration(IAppBuilder app) {
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
app.MapSignalR("/signalr", new Microsoft.AspNet.SignalR.HubConfiguration());
}
My Hub:
public class ServiceStatusHub : Hub {
private static IHubContext hubContext =
GlobalHost.ConnectionManager.GetHubContext<ServiceStatusHub>();
public static void SetStatus(string message) {
hubContext.Clients.All.acknowledgeMessage(message);
}
}
And in my Api Controler I call:
ServiceStatusHub.SetStatus("Status changed!");
I made console application to test Api, added Signal R client and class:
class SignalRMasterClient {
public string Url { get; set; }
public HubConnection Connection { get; set; }
public IHubProxy Hub { get; set; }
public SignalRMasterClient(string url) {
Url = url;
Connection = new HubConnection(url, useDefaultUrl: false);
Hub = Connection.CreateHubProxy("ServiceStatusHub");
Connection.Start().Wait();
Hub.On<string>("acknowledgeMessage", (message) =>
{
Console.WriteLine("Message received: " + message);
/// TODO: Check status of the LDAP
/// and update status to Web API.
});
}
public void SayHello(string message) {
Hub.Invoke("hello", message);
Console.WriteLine("hello method is called!");
}
public void Stop() {
Connection.Stop();
}
}
program.cs:
var client = new SignalRMasterClient("myUrl.com/signalr");
// Send message to server.
client.SayHello("Message from client to Server!");
I getting 500 Internal Server Error.
How can I test is my Web Api signalR works for sure?
I see some problems:
1) You do not need the hubContext field in your hub. You inherit from Hub. This class contains allready a "Clients" property .
public class ServiceStatusHub : Hub {
public static void SetStatus(string message) {
Clients.All.acknowledgeMessage(message);
}
}
2) Log errors at starting of server.
public SignalRMasterClient(string url) {
Url = url;
Connection = new HubConnection(url, useDefaultUrl: false);
Hub = Connection.CreateHubProxy("ServiceStatusHub");
Connection.Start().ContinueWith(task => { if (task.IsFaulted) {
Console.WriteLine("There was an error opening the connection:{0}",
task.Exception.GetBaseException());
} else {
Console.WriteLine("Connected");
}
});
Hub.On<string>("acknowledgeMessage", (message) =>
{
Console.WriteLine("Message received: " + message);
/// TODO: Check status of the LDAP
/// and update status to Web API.
}).Wait();
}
3) Check Client url. You need no signalr there in your path at creation of your client.
just:
var client = new SignalRMasterClient("myUrl.com/");
Here you will find a running sample which does all you need:
SignalR Console app example

OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL timed out after 60 seconds

Here is my issue:
I am just trying to run basic tests, just to try this out, and I keep running into the exception: "OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL (url here) timed out after 60 seconds".
I am using the most up to date Selenium, which is 3.3.0, and the most current Selenium Support, which is also 3.3.0.
I have set up the driver:
public static class Driver
{
public static IWebDriver Instance { get; set; }
public static void Initialize()
{
Instance = new ChromeDriver();
}
public static void Close()
{
Instance.Close();
}
}
And I am running a basic test to login to a wordpress account, from a different class, to keep the test separated from the logic:
[TestMethod]
public void Test_LogIn()
{
WordPressLoginPage.GoTo();
WordPressLoginPage.LoginAs("*******").WithPassword("*******").Login();
}
And here is the methods that the test is calling:
public class WordPressLoginPage
{
private const string LoginUrl = "https://wordpress.com/wp-login.php";
public static void GoTo()
{
Driver.Instance.Navigate().GoToUrl(LoginUrl);
var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(5));
wait.Until(d => d.SwitchTo().ActiveElement().GetAttribute("id") == ("user_login"));
}
public static LoginCommmand LoginAs(string userName)
{
return new LoginCommmand(userName);
}
}
public class LoginCommmand
{
private readonly string _userName;
private string _password;
public LoginCommmand(string userName)
{
_userName = userName;
}
public LoginCommmand WithPassword(string password)
{
_password = password;
return this;
}
public void Login()
{
var loginInput = Driver.Instance.FindElement(By.Id("user_login"));
loginInput.SendKeys(_userName);
var passwordInput = Driver.Instance.FindElement(By.Id("user_pass"));
passwordInput.SendKeys(_password);
var loginSubmit = Driver.Instance.FindElement(By.Id("wp-submit"));
loginSubmit.Submit();
var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(65));
wait.Until(d => d.SwitchTo().ActiveElement().GetAttribute("id") == ("search-component-1"));
}
}
The exception tells me that the timeout happens here:
loginSubmit.Submit();
and I can see that the page is still loading for probably more than two minutes after I started running it.
I have looked at other questions here regarding the same exception, but none of the answers from those seems to help here.
I, too, was coming across this issue in my framework, but not when individual tests were run. This was posing an issue when I was running multiple tests in parallel, and always on the .Submit() method with ChromeDriver.
In order to rectify this, I had to modify my scripts to click on a submit button instead. After this, my scripts ran fine.
For the record, I am using WebDriver and Support packages v3.4.0, ChromeDriver v2.29.0 and Chrome v58.0.3029.110.
I also encountered this problem. The issue occurred as a result of password pass through. The test team were all signing into their Virtual machines with the same credentials, Username: X and Password: Y. Similarity, the Virtual machine which stored the application we were testing against also had the same credentials.
However, at a particular point in time one of the developers changed Password from Y to Z. So the authentication for requesting a server response was failing in the background. You effectively need some form of an authentication service for your test project. See below for a good start point:
https://sqa.stackexchange.com/questions/2277/using-selenium-webdriver-with-windows-authentication

Exchange Server 2007 Transport Agent Issue

This is the first time i am working on Exchange Server Development. Below is a simple Transport Agent that i am using, this agent should simply update the email Subjects as shown below in the code.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Smtp;
namespace MyAgents
{
public sealed class MyAgentFactory : SmtpReceiveAgentFactory
{
public override SmtpReceiveAgent CreateAgent(SmtpServer server)
{
return new MyAgent();
}
}
public class MyAgent : SmtpReceiveAgent
{
public MyAgent()
{
this.OnEndOfData += new EndOfDataEventHandler(MyEndOfDataHandler);
}
private void MyEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
{
e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject;
}
}
}
Below is the Powershell script i am using to install the Agent.
Net Stop MSExchangeTransport
Install-TransportAgent -Name MyAgent -AssemblyPath EmailLogger.dll -TransportAgentFactory MyAgents.MyAgentFactory
Enable-TransportAgent -Identity MyAgent
Net Start MSExchangeTransport
Agent installed successfully using Exchange Management Shell.
Now when i send/receive emails in exchange, Email subjects are not modified. Emails have their original subjects. I don't know why?
I also performed the steps mentioned in below links to debug the Agent but breakpoints are not being hit by Visual Studio Debugger.
http://www.sf-tools.net/Messaging/tabid/55/EntryId/163/Exchange-2010-Transport-Agent.aspx
Debugging MS Exchange 2007 Transport Agent
http://omarjames.com/blog/index.php/debugging-exchange-transport-agent/
My System Configuration
I am using the Exchange Server 2007 Virtual Machine provided by Microsoft from link below
http://www.microsoft.com/en-pk/download/details.aspx?id=14901
I also installed the Visual Studio 2008 on the VM for debugging.
Please help me in resolving the issue?
Problem Solved. :)
I must use Routing Agent instead of SmtpReceive Agent because only Routing Agents are guaranteed to see all the Emails passing through Exchange Server.
Below is the modified working code, Everything else remains same
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Routing;
namespace MyAgents
{
public sealed class MyAgentFactory : RoutingAgentFactory
{
public override RoutingAgent CreateAgent(SmtpServer server)
{
return new MyAgent();
}
}
public class MyAgent : RoutingAgent
{
public MyAgent()
{
this.OnSubmittedMessage += new SubmittedMessageEventHandler(this.MySubmittedMessageHandler);
}
public void MySubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
{
e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject;
}
}
}

scenario background- launch wcf service

I'm testing a WCF service methods using specflow and nunit; my scenarios look like the following:
Feature: GetAccount
Testing API method 'get account'
Background:
Given Server is running
Scenario: Succesful Get
Given An Existing Account
When I call the GetAccount API method With password = "123"
Then the result should be Success
I'm not sure on how to implement the background step;
The server can be run as console / windows service using Topshelf-
private static void Main()
{
Host host = HostFactory.New(config =>
{
config.Service<ServiceInitializer>(service =>
{
service.ConstructUsing(s => new ServiceInitializer());
service.WhenStarted((s, control) => s.Start(control));
service.WhenStopped((s, control) => s.Stop(control));
});
config.RunAsPrompt();
});
host.Run();
}
public class ServiceInitializer : ServiceControl
{
private readonly ILog m_log;
public ServiceInitializer()
{
log4net.Config.XmlConfigurator.Configure();
m_log = LogManager.GetLogger("Server");
}
public bool Start(HostControl hostControl)
{
try
{
var host = new IoCServiceHost(typeof(MyService));
host.Open();
m_log.Info("Server is now open.");
return true;
}
catch (Exception exception)
{
m_log.Fatal("Initialization of service failed",exception);
return false;
}
}
public bool Stop(HostControl hostControl)
{
m_log.Info("Server has closed");
return true;
}
}
should I just execute the .exe service file, or can I use my ServiceInitializer in some way? perhaps I could use nUnit's [SetUpFixture]?
Are there any Specflow best practices?
Let's consider what you want to test.
Do you need to test that Windows correctly runs services?
Do you need to test that Topshelf correctly starts services?
Or do you just want to test that GetAccount works?
I'll bet that you are using Topshelf to make your life easier, so do that and trust that their code works within windows. Its a valid assumption since there code will be used in many places and they probably have their own test suites, and if your assumption is wrong, then test it later when you find the problems.
So all you really need is
[BeforeFeature]
public void Background()
{
FeatureContext.Current["Host"] =new MyHostObject();
}
[When("I call GetAccount API method with password =\"(\.*)\"")]
public void WhenICallGetAccount(string password)
{
var host = (MyHostObject)FeatureContext.Current["Host"];
ScenarioContext.Current["Account"] = host.GetAccount(password);
}
[Then("the result should be success")]
public void ThenTheResultShouldBeSuccessful()
{
var account = (MyAccount)ScenarioContext.Current["Account"];
//assuming using Should;
account.ShouldNotBeNull();
}

Categories