Pyro - Python Remote Objects

Für die Vorlesung “Verteilte Systeme” musste jeder aus unserem Studiengang eine kleine Ausarbeitung erstellen. Damit diese Arbeiten nicht nur unseren Noten helfen, poste ich diese, im Namen der Autoren, auf meinem Blog.  Angefangen mit der Ausarbeitung von Oliver Burger zum Thema “Pyro – Python Remote Objects”.

 

Zusammenfassung

In der hier vorliegenden Arbeit werden die Grundzüge der Programmierung mit der Pyro-Bibliothek zum Erstellen verteilter Anwendungen unter Python dargestellt. Hierbei soll das grundlegende Vorgehen der Programmierung dargestellt werden sowie die Architektur dieser Anwendungen betrachtet werden.

 

Ausarbeitung

 

Slides

 

Download Links

Pyro - Python Remote Objects
Pyro - Python Remote Objects
Pyro_-_Python_Remote_Objects.pdf
Version: 1.0
174.9 KiB
3 Downloads
Details...
Pyro - Python Remote Objects Slides
Pyro - Python Remote Objects Slides
Pyro_-_Python_Remote_Objects-Praesentation.pdf
Version: 1.0
321.8 KiB
3 Downloads
Details...

Async and await in .NET 4.5

Yesterday I was playing around with Windows 8 and VisualStudio 11 and because my University is developing a web service to connect to the class schedule I played around with the semi-finished service and tried to get some data out.

The implementation of the alpha service is horrible, there is no authorisation and there isn´t planed some, everyone can get the usernames of the students and their class schedules. Also there is no limitation of the output, I had to limit the output myself to avoid a crashing program while my integer was too small. Finally you can´t get a person by his unique mail address, you have to search for the last name and let the user select the right person because the mail is not provided and finally the search results are redundant.

So in short terms, the service is buggy but that´s not the problem, that´s a challenge ;-)
Anyway my intension was to play around with the .NET-Framework 4.5 and the service was just an opportunity.

I used async and await the first time and I really liked it :-)
It is very easy to use, with async in the header you can define your method as asynchronous and with the use of await you can select a specific function inside the asynchronous method that it needs to wait for. No need for callbacks anymore ;-)
A very good article about asyncawait and the pros and contras can be found at msdn (german).

Below you can see my WPF solution. I can´t post the whole project because the service shouldn´t be available for everyone right now and it isn´t – there are some more hints needed to get it to work properly..

The only two methods I implemented (the service was implemented via service reference in VisualStudio):

private async void TextBoxUsername_TextChanged(object sender, TextChangedEventArgs e)
{
    DataGridUsernames.ItemsSource = null;
    DataGridCourse.ItemsSource = null;

	// min req length
    if (TextBoxUsername.GetLineLength(0) > 2)
        using (Service1Client client = new Service1Client())
        {
            try
            {
				// because the service defines no max output
                ((HttpBindingBase)(client.Endpoint.Binding)).MaxReceivedMessageSize = Int32.MaxValue;

                var users = await client.getUsersAsync(TextBoxUsername.Text);
                DataGridUsernames.ItemsSource = from user in users select new { user.firstName, user.lastName, user.userId };
            }
            catch (EndpointNotFoundException)
            {
                MessageBox.Show("Service unavailable!", "Info", MessageBoxButton.OK);
            }
            catch
            {
                MessageBox.Show("Undefined Error!", "Error", MessageBoxButton.OK);
            }
        }
}

private async void DataGridUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (DataGridUsernames.SelectedItem != null)
        try
        {
            using (Service1Client client = new Service1Client())
            {
                TimetabelListType[] courses = await client.getMyTimeTableForDayAsync(DateTimePicker.DisplayDate,
																((dynamic)DataGridUsernames.SelectedItem).userId);
                DataGridCourse.ItemsSource = null;
                DataGridCourse.ItemsSource = from course in courses select new { course.title,
																				 course.instructor,
																				 course.startDate,
																				 course.endDate };
            }
        }
        catch (EndpointNotFoundException)
        {
            MessageBox.Show("Service unavailable!", "Info", MessageBoxButton.OK);
        }
        catch
        {
            MessageBox.Show("Undefined Error!", "Error", MessageBoxButton.OK);
        }
}

And finally a pictue of the GUI (sorry for the noise):

Edit: A frind asked me for the XAML – see below ;-)

<Window x:Class="WSDL-______.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="______ Querry" Icon="favicon.ico"
		Height="340" MinHeight="340"
		Width="550" MinWidth="550">
    <DockPanel LastChildFill="True" >
        <Grid DockPanel.Dock="Top" VerticalAlignment="Bottom" Margin="5,10,5,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Content="Username"/>
            <TextBox Grid.Column="1" Name="TextBoxUsername" TextWrapping="Wrap" TextChanged="TextBoxUsername_TextChanged"/>
            <DatePicker Grid.Column="2" Name="DateTimePicker" BorderThickness="0" Margin="15,0,0,0"/>
        </Grid>
        <Grid DockPanel.Dock="Bottom" Margin="5,10,5,5">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="90" Height="*" />
                <RowDefinition Height="Auto" />
                <RowDefinition MinHeight="90" Height="*" />
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Content="Anwender auswählen:"/>
            <DataGrid Grid.Row="1" Name="DataGridUsernames" SelectionChanged="DataGridUsers_SelectionChanged" IsReadOnly="True"/>
            <Label Grid.Row="2" Content="Kursübersicht"/>
            <DataGrid Grid.Row="3" Name="DataGridCourse" />
        </Grid>
    </DockPanel>
</Window>

Protected subdomain/domain alias htaccess

For a new costumer project I had the problem to protected a subdomain by a basic authentication. The Problem was that the specific folder was the target for 5 other first level domains. To ensure that the other domains are still available i made a .htaccess hack that i like to share with you ;-)

AuthUserFile /*your_path/.htpasswd
AuthName "Locked Test"
AuthType Basic
Require valid-user

SetEnvIf Host SUB.DOMAIN.TLD secure_content

Order Allow,Deny
Allow from all
Deny from env=secure_content

Satisfy Any

Simple TCP/IP client/server application

Intro

For a university lecture I had to write a simple application to demonstrate a client/server communication over TCP/IP. I know there are many demos in the world wide web and now there is one more ;-)

Code

Below I post you the code and at the end of the post you will find a ZIP-file with the project – have fun.

Server

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Server
{
    class Program
    {
        const int port = 8001;
        const string ip = "127.0.0.1";
        const int maxBuffer = 100;

        static void Main(string[] args)
        {
            try
            {
                IPAddress ipAddress = IPAddress.Parse(ip);
                TcpListener tcpListener = new TcpListener(ipAddress, port);
                tcpListener.Start();

                Console.WriteLine(string.Format("The server is running at port {0}..", port));
                Console.WriteLine(string.Format("The local End point is: {0}", tcpListener.LocalEndpoint));

                Console.WriteLine("\nWaiting for connection..");
                using (Socket socket = tcpListener.AcceptSocket())
                {
                    Console.WriteLine(string.Format("Connection accepted from: {0}", socket.RemoteEndPoint));

                    byte[] receiveBuffer = new byte[maxBuffer];
                    int usedBuffer = socket.Receive(receiveBuffer);

                    Console.WriteLine("\nRecieved..");
                    for (int i = 0; i < usedBuffer; i++)
                        Console.Write(Convert.ToChar(receiveBuffer[i]));

                    Console.WriteLine("\n\nSent acknowledgement");
                    socket.Send(new ASCIIEncoding().GetBytes("The string was recieved by the server."));

                    Console.ReadLine();
                }

                tcpListener.Stop();
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("Error: {0}", e.StackTrace));
            }
        }
    }
}

Client

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace Client
{
    class Program
    {
        const int port = 8001;
        const string ip = "127.0.0.1";
        const int maxBuffer = 100;

        static void Main(string[] args)
        {
            try
            {
                using (TcpClient tcpClient = new TcpClient())
                {
                    Console.WriteLine("Connecting..");
                    tcpClient.Connect(ip, port);
                    Console.WriteLine("Connected");

                    Console.Write("\nEnter the string to be transmitted: ");
                    String inputString = Console.ReadLine();
                    Stream networkStream = tcpClient.GetStream();

                    byte[] sendBuffer = new ASCIIEncoding().GetBytes(inputString);
                    Console.WriteLine("Transmitting..\n");
                    networkStream.Write(sendBuffer, 0, sendBuffer.Length);

                    Console.WriteLine("Receive acknowledgement from server..");
                    byte[] receiveBuffer = new byte[maxBuffer];
                    int k = networkStream.Read(receiveBuffer, 0, maxBuffer);

                    for (int i = 0; i < k; i++)
                        Console.Write(Convert.ToChar(receiveBuffer[i]));

                    Console.ReadLine();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("Error: {0}", e.StackTrace));
            }
        }
    }
}

Download Link

ClientServerProgram
ClientServerProgram
ClientServerProgram.zip
Version: 1.0
13.6 KiB
22 Downloads
Details...

Work with Exchange Web Services

The following code has cost me allot of time. It was very hard to find the pieces and put them together. So I hope I can help a few of you with that post ;-)

The Problem

The problem was that I need to access different Exchange accounts via Exchange Web Services (EWS) and read out the mailbox size.

First

To do this I first used a view only account in the active directory that I have activated for impersonation by typing the following code into the Exchange-Shell:

Get-ExchangeServer
| where {$_.IsClientAccessServer -eq $TRUE}
| ForEach-Object {Add-ADPermission -Identity $_.distinguishedname -User (Get-User -Identity User1 | select-object)
    .identity -extendedRight ms-Exch-EPI-Impersonation}

You can find an explanation to this code on msdn: http://msdn.microsoft.com/en-us/library/bb204095(EXCHG.80).aspx

Second

Then I set up the connection string to the EWS:

// Certification Validation always true
ServicePointManager.ServerCertificateValidationCallback =
                    delegate(
                        Object obj,
                        X509Certificate certificate,
                        X509Chain chain,
                        SslPolicyErrors errors)
                    {
                        return true;
                    };

// Setup connection string
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new NetworkCredential("viewadmin", "password", "FQDN");
service.AutodiscoverUrl("viewadmin@FQDN");

Third

Thirdly I used impersonation to connect to another mailbox account:

// Impersonate
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user@FQDN");

Finally

And finally I requested the folder size with this nice little piece of code:

private static readonly ExtendedPropertyDefinition PidTagMessageSizeExtended
                        = new ExtendedPropertyDefinition(0xe08, MapiPropertyType.Long);

/// <summary>
/// Gets the size of the mailbox in kilobytes.
/// </summary>
/// <param name="service">The ExchangeService object.</param>
/// <returns>Returns the used kilobytes in double.</returns>
public static double GetMailboxSize(ExchangeService service)
{
    var offset = 0;
    const int pagesize = 12;
    long size = 0;

    FindFoldersResults folders;
    do
    {
        folders = service.FindFolders(WellKnownFolderName.MsgFolderRoot,
                                      new FolderView(pagesize, offset, OffsetBasePoint.Beginning)
                                      {
                                          Traversal = FolderTraversal.Deep,
                                          PropertySet =
                                              new PropertySet(BasePropertySet.IdOnly, PidTagMessageSizeExtended,
                                                              FolderSchema.DisplayName)
                                      });

        foreach (var folder in folders)
        {
            long folderSize;
            if (folder.TryGetProperty(PidTagMessageSizeExtended, out folderSize))
                size += folderSize;
        }
        offset += pagesize;
    } while (folders.MoreAvailable);

    return size;
}

 

I hope I could help you. If you have improvements on the code don´t hazle to comment ;-)