Basics of Git Rebase

Git Rebase is only one of the powerful features of git and it allows you to have a clean history in a highly branching workflow.
2013-03-30 18:18
Tugberk Ugurlu


You may wonder why the title starts with "Basics". The answer is simple: I know only the basics of git rebase :) It's only one of the powerful features of git and it allows you to have a clean history in a highly branching workflow. "Rebase" is quite powerful as mentioned and what I'm about to show you is only one of the reasons why to use rebase. I highly recommend Keith Dahlby's NDC talk which he took some time to show the rebase feature.

Let's see the easiest sample where rebase comes handy. We have the following history where we have two branches: master and feature-1.

image

Typically, what you would do here is to merge the feature-1 branch onto master which is fairly reasonable and it works. However, it creates you a unnecessary commit + a ridiculous graph which would be a mess if you think of hundreds of branches:

image

What you can do with rebase is to patch the feature-1 branch onto master. Later then, you can merge from there. The following command is what you need to run:

image

After running the rebase command, we can run "gitk –all" to see the graph:

image

It's now nice clean history. Notice that the master is still pointing where it was. It's because we haven't merge the feature-1 branch yet. Let's checkout to master branch and run "git merge feature-1" to merge feature-1 branch onto master branch:

image

Nicely done! Open up the gitk one more time and see the clean history:

image

After we remove the feature-1 branch by running "git branch –D feature-1", we won't have any trace from feature-1 branch which is absolutely OK as feature branches are just the implementation details, that's all.

image

Rebase can hurt

With git rebase, at the very basic level, you are messing with the history which can be dangerous depending on the case. On the other hand, when you have a collision, it's not a picnic to solve those collisions with interactive rebase without a deep firsthand knowledge but it's worth looking into even if it seems hard at the first glance Smile

Microsoft Web Camps Istanbul on the 6th of April

One leg of Microsoft Web Camps spring 2013 tour will be held in Microsoft Istanbul office on the 6th of April, 2013.
2013-03-23 16:21
Tugberk Ugurlu


WebCamps-Spring-2013

This is an awesome news that I am proud of to write about. I think it all started out with my reply to Brady Gaster on twitter:

And it's now a real deal thanks to awesome Web Camps team! One leg of Microsoft Web Camps spring 2013 tour will be held in Microsoft Istanbul office on the 6th of April, 2013. It will be a full day event. Jon Galloway, Umit Sunar and me will be giving talks on various latest Microsoft Web Stack technologies including Windows Azure, ASP.NET Web API, ASP.NET SignalR, ASP.NET MVC and so on. You can see the typical agenda of Web Camps here.

You can also find more about Web Camps spring 2013 tour from Jon Galloway's and Brady Gaster's blog posts:

There are finite number of seats available. So, register ASAP to participate this great event from the following link:

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032548038&Culture=TR-TR&community=0

See you at Web Camps Smile

MSP Turkey Kickoff Microsoft Web Stack Presentation Slides, Samples and Links

I was at MSFT Istanbul office yesterday to give a presentation on Microsoft Web Stack for MSPs. Slides and samples are now available online.
2013-02-09 12:22
Tugberk Ugurlu


I was at MSFT Istanbul office yesterday to give a presentation on Microsoft Web Stack for MSPs. It went pretty well I think. It was mostly focused on ASP.NET MVC 4, SignalR and ASP.NET Web API. You can get the slides for the presentation from my Speakerdeck account.

Source code for the sample applications I showed is available on GitHub: https://github.com/tugberkugurlu/MSPKickOff201302MSFTWebStack.

I also showed the Electric Plum's iPhone and iPad simulator and I used it right from VS. I followed through this awesome blog post from Scott Hanselman to set this up: Simulating an iPhone or iPad browser for ASP.NET Mobile Web Development with WebMatrix 2 or Visual Studio 2012. You can do the same. Here are a few other links which were touched upon during the presentation:

General Links

ASP.NET MVC

ASP.NET SignalR

ASP.NET Web API

I would like to thank our MVP Lead Sinem Eylem Arslan and Mustafa Kasap for the opportunity. Also, special thanks go to XOMNI team (Daron Yondem, Gökhan Gülbiz, ilkay ilknur) for helping me to get though those 2 days in Istanbul. I have to say this: they seriously know how to live Smile Breakfast was amazing Smile

Autofac Open Generics Feature to Register Generic Services

Autofac, an awesome IoC container for .NET platform, has an out of the box generic service registration feature which we will quickly cover in this blog post.
2013-02-05 08:46
Tugberk Ugurlu


This is going to be a quick and dirty blog post but hopefully, will take this giant stupidity out of me. Autofac, an awesome IoC container for .NET platform, has an out of the box generic service registration feature and I assume nearly all IoC containers have this today which makes me feel stupid because I have been knowing this for only a month or so Smile I was doing something like below before.

private static void RegisterRepositories(ContainerBuilder builder) {
 
    Type baseEntityType = typeof(BaseEntity);
    Assembly assembly = baseEntityType.Assembly;
    IEnumerable<Type> entityTypes = assembly.GetTypes().Where(
        x => x.IsSubclassOf(baseEntityType));
        
    foreach (Type type in entityTypes) {
 
        builder.RegisterType(typeof(EntityRepository<>)
               .MakeGenericType(type))
               .As(typeof(IEntityRepository<>).MakeGenericType(type))
               .InstancePerApiRequest();
    }
}

Then, Ben Foster pinged me on twitter:

This tweet made me look for alternative approaches and I found out the Autofac's generic service registration feature. Here is how it looks like now:

private static void RegisterRepositories(ContainerBuilder builder) {
 
    builder.RegisterGeneric(typeof(EntityRepository<>))
           .As(typeof(IEntityRepository<>))
           .InstancePerApiRequest();
}

Way better! Autofac also respects generic type constraints. Here is a quote from the Autofac documentation:

Autofac respects generic type constraints. If a constraint on the implementation type makes it unable to provide a service the implementation type will be ignored.

If you didn't know this feature before, you do know it now Smile Enjoy it!

Hierarchical Resource Structure in ASP.NET Web API

This post explains the concerns behind the hierarchical resource structure in ASP.NET Web API such as routing, authorization and ownership.
2013-02-04 08:11
Tugberk Ugurlu


I came across a question on Stackoverflow today about the hierarchical resource structure in ASP.NET Web API: http://stackoverflow.com/questions/14674255. The question is basically about the following issue:

I have the following schema that I'd like to implement in ASP.NET Web API. What is the proper approach?

http://mydomain/api/students
http://mydomain/api/students/s123
http://mydomain/api/students/s123/classes
http://mydomain/api/students/s123/classes/c456

With this nice hierarchical approach, you have more concerns that routing here in terms of ASP.NET Web API. There is a good sample application which adopts the hierarchical resource structure: PingYourPackage. I definitely suggest you to check it out.

Let me explain the concerns here in details by setting up a sample scenario. This may not be the desired approach for these types of situations but lays out the concerns very well and if you have a better way to eliminate these concerns, I'd be more that happy to hear those.

Let's say you have the below two affiliates inside your database for a shipment company:

  • Affiliate1 (Id: 100)
  • Affiliate2 (Id: 101)

And then assume that these affiliates have some shipments attached to them:

  • Affiliate1 (Key: 100)
    • Shipment1 (Key: 100)
    • Shipment2 (Key: 102)
    • Shipment4 (Key: 104)
  • Affiliate2 (Key: 101)
    • Shipment3 (Key: 103)
    • Shipment5 (Key: 105)

Finally, we want to have the following resource structure:

  • GET api/affiliates/{key}/shipments
  • GET api/affiliates/{key}/shipments/{shipmentKey}
  • POST api/affiliates/{key}/shipments
  • PUT api/affiliates/{key}/shipments/{shipmentKey}
  • DELETE api/affiliates/{key}/shipments/{shipmentKey}

In view of ASP.NET Web API, we have three obvious concerns here: routing, authorization and ownership. Let's go through this one by one.

The below code snippets have been taken from the PingYourPackage source code. They won't probably work if you copy and paste them but you will get the idea.

Routing Concerns

Assume that we are sending a GET request against /api/affiliates/105/shipments/102 (considering our above scenario). Notice that the affiliate key is 105 here which doesn't exist. So, we would want to terminate the request here ASAP. We can achieve this with a per-route message handler as early as possible. The following AffiliateShipmentsDispatcher is responsible for checking the affiliate existence and acting on the result.

public class AffiliateShipmentsDispatcher : DelegatingHandler {

  protected override Task<HttpResponseMessage> SendAsync(
      HttpRequestMessage request, 
      CancellationToken cancellationToken) {

      // We know at this point that the {key} route variable has 
      // been supplied. Otherwise, we wouldn't be here. So, just get it.
      IHttpRouteData routeData = request.GetRouteData();
      Guid affiliateKey = Guid.ParseExact(routeData.Values["key"].ToString(), "D");

      IShipmentService shipmentService = request.GetShipmentService();
      if (shipmentService.GetAffiliate(affiliateKey) == null) {

          return Task.FromResult(
              request.CreateResponse(HttpStatusCode.NotFound));
      }

      return base.SendAsync(request, cancellationToken);
  }
}

I am here using a few internal extension methods which are used inside the project but the idea is simple: go to the database and check the existence of the affiliate. If it doesn't exist, terminate the request and return back the "404 Not Found" response. If it exists, continue executing by calling the base.SendAsync method which will invoke the next message handler inside the chain. Which message handler is the next here? Good question, you dear reader! It's going to be the HttpControllerDispatcher which basically puts us inside the controller pipeline. To attach this handler to a route, we need to create a pipeline first to include the controller pipeline by chaining AffiliateShipmentsDispatcher and HttpControllerDispatcher together. The following code snippet shows the AffiliateShipmentsHttpRoute registration.

public class RouteConfig {

    public static void RegisterRoutes(HttpConfiguration config) {

        var routes = config.Routes;

        // Pipelines
        HttpMessageHandler affiliateShipmentsPipeline =
            HttpClientFactory.CreatePipeline(
                new HttpControllerDispatcher(config),
                new[] { new AffiliateShipmentsDispatcher() });

        // Routes
        routes.MapHttpRoute(
            "AffiliateShipmentsHttpRoute",
            "api/affiliates/{key}/shipments/{shipmentKey}",
            defaults: new { controller = "AffiliateShipments", shipmentKey = RouteParameter.Optional },
            constraints: null,
            handler: affiliateShipmentsPipeline);

        routes.MapHttpRoute(
            "DefaultHttpRoute",
            "api/{controller}/{key}",
            defaults: new { key = RouteParameter.Optional },
            constraints: null);
    }
}

Authorization Concerns

If you have some type of authentication in place, you would want to make sure (in our scenario here) that the authenticated user and the requested affiliate resource is related. For example, assume that Affiliate1 is authenticated under the Affiliate role and you have the AuthorizeAttribute registered to check the "Affiliate" role authorization. In this case, you will fail miserably because this means that Affiliate1 can get to the following resource: /api/affiliates/101/shipments which belongs to Affiliate2. We can eliminate this problem with a custom AuthorizeAttribute which is similar to below one:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AffiliateShipmentsAuthorizeAttribute : AuthorizeAttribute {

    public AffiliateShipmentsAuthorizeAttribute() {

        base.Roles = "Affiliate";
    }

    public override void OnAuthorization(HttpActionContext actionContext) {
        
        base.OnAuthorization(actionContext);

        // If not authorized at all, don't bother checking for the 
        // user - affiliate relation
        if (actionContext.Response == null) { 

            // We are here sure that the request has been authorized and 
            // the user is in the Affiliate role. We also don't need 
            // to check the existence of the affiliate as it has 
            // been also already done by AffiliateShipmentsDispatcher.

            HttpRequestMessage request = actionContext.Request;
            Guid affiliateKey = GetAffiliateKey(request.GetRouteData());
            IPrincipal principal = Thread.CurrentPrincipal;
            IShipmentService shipmentService = request.GetShipmentService();
            bool isAffiliateRelatedToUser =
                shipmentService.IsAffiliateRelatedToUser(
                    affiliateKey, principal.Identity.Name);

            if (!isAffiliateRelatedToUser) {

                // Set Unauthorized response as the user and 
                // affiliate isn't related to each other. You might
                // want to return "404 NotFound" response here if you don't
                // want to expose the existence of the affiliate.
                actionContext.Response = 
                    request.CreateResponse(HttpStatusCode.Unauthorized);
            }
        }
    }

    private static Guid GetAffiliateKey(IHttpRouteData routeData) {

        var affiliateKey = routeData.Values["key"].ToString();
        return Guid.ParseExact(affiliateKey, "D");
    }
}

This will be registered at the controller level for the AffiliateShipmentsController.

Ownership Concerns

Consider this URI for an HTTP GET request: /api/affiliates/100/shipments/102. This URI should get us the correct data. However, what would happen for the this URI: /api/affiliates/100/shipments/103? This should get you a "404 Not Found" HTTP response because the affiliate whose Id is 100 doesn't own the shipment whose id is 103. Inside the PingYourPackage project, I ensured the ownership of the resource with the following authorization filter which will be applied to proper action methods.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class EnsureShipmentOwnershipAttribute 
    : Attribute, IAuthorizationFilter {

    private const string ShipmentDictionaryKey = 
        "__AffiliateShipmentsController_Shipment";
        
    public bool AllowMultiple { get { return false; } }

    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation) {

        // We are here sure that the user is authanticated and request 
        // can be kept executing because the AuthorizeAttribute has 
        // been invoked before this filter's OnActionExecuting method.
        // Also, we are sure that the affiliate is associated with
        // the currently authanticated user as the previous action filter 
        // has checked against this.
        IHttpRouteData routeData = actionContext.Request.GetRouteData();
        Uri requestUri = actionContext.Request.RequestUri;

        Guid affiliateKey = GetAffiliateKey(routeData);
        Guid shipmentKey = GetShipmentKey(routeData, requestUri);

        // Check if the affiliate really owns the shipment
        // whose key came from the request. We don't need to check the 
        // existence of the affiliate as this check has been already 
        // performed by the AffiliateShipmentsDispatcher.
        IShipmentService shipmentService = 
            actionContext.Request.GetShipmentService();
        Shipment shipment = shipmentService.GetShipment(shipmentKey);

        // Check the shipment existance
        if (shipment == null) {

            return Task.FromResult(
                new HttpResponseMessage(HttpStatusCode.NotFound));
        }

        // Check the shipment ownership
        if (shipment.AffiliateKey != affiliateKey) {

            // You might want to return "404 NotFound" response here 
            // if you don't want to expose the existence of the shipment.
            return Task.FromResult(
                new HttpResponseMessage(HttpStatusCode.Unauthorized));
        }

        // Stick the shipment inside the Properties dictionary so 
        // that we won't need to have another trip to database.
        // The ShipmentParameterBinding will bind the Shipment param
        // if needed.
        actionContext.Request
            .Properties[ShipmentDictionaryKey] = shipment;

        // The request is legit, continue executing.
        return continuation();
    }

    private static Guid GetAffiliateKey(IHttpRouteData routeData) {

        var affiliateKey = routeData.Values["key"].ToString();
        return Guid.ParseExact(affiliateKey, "D");
    }

    private static Guid GetShipmentKey(
        IHttpRouteData routeData, Uri requestUri) {

        // We are sure at this point that the shipmentKey value has been
        // supplied (either through route or quesry string) because it 
        // wouldn't be possible for the request to arrive here if it wasn't.
        object shipmentKeyString;
        if (routeData.Values.TryGetValue("shipmentKey", out shipmentKeyString)) {

            return Guid.ParseExact(shipmentKeyString.ToString(), "D");
        }

        // It's now sure that query string has the shipmentKey value
        var quesryString = requestUri.ParseQueryString();
        return Guid.ParseExact(quesryString["shipmentKey"], "D");
    }
}

Now, this filter can be applied to proper action methods to allow the proper authorization. At the very end, the AffiliateShipmentsController class looks clean and readable:

[AffiliateShipmentsAuthorize]
public class AffiliateShipmentsController : ApiController {

    // We are OK inside this controller in terms of 
    // Affiliate existance and its relation with the current 
    // authed user has been checked by the handler 
    // and AffiliateShipmentsAuthorizeAttribute.

    // The action method which requests the shipment instance:
    // We can just get the shipment as the shipment 
    // existance and its ownership by the affiliate has been 
    // approved by the EnsureShipmentOwnershipAttribute.
    // The BindShipmentAttribute can bind the shipment from the
    // Properties dictionarty of the HttpRequestMessage instance
    // as it has been put there by the EnsureShipmentOwnershipAttribute.

    private const string RouteName = "AffiliateShipmentsHttpRoute";
    private readonly IShipmentService _shipmentService;

    public AffiliateShipmentsController(IShipmentService shipmentService) {

        _shipmentService = shipmentService;
    }

    public PaginatedDto<ShipmentDto> GetShipments(
        Guid key, 
        PaginatedRequestCommand cmd) {

        var shipments = _shipmentService
            .GetShipments(cmd.Page, cmd.Take, affiliateKey: key);

        return shipments.ToPaginatedDto(
            shipments.Select(sh => sh.ToShipmentDto()));
    }

    [EnsureShipmentOwnership]
    public ShipmentDto GetShipment(
        Guid key, 
        Guid shipmentKey, 
        [BindShipment]Shipment shipment) {

        return shipment.ToShipmentDto();
    }

    [EmptyParameterFilter("requestModel")]
    public HttpResponseMessage PostShipment(
        Guid key, 
        ShipmentByAffiliateRequestModel requestModel) {

        var createdShipmentResult =
            _shipmentService.AddShipment(requestModel.ToShipment(key));

        if (!createdShipmentResult.IsSuccess) {

            return new HttpResponseMessage(HttpStatusCode.Conflict);
        }

        var response = Request.CreateResponse(HttpStatusCode.Created,
            createdShipmentResult.Entity.ToShipmentDto());

        response.Headers.Location = new Uri(
            Url.Link(RouteName, new { 
                key = createdShipmentResult.Entity.AffiliateKey,
                shipmentKey = createdShipmentResult.Entity.Key
            })
        );

        return response;
    }

    [EnsureShipmentOwnership]
    [EmptyParameterFilter("requestModel")]
    public ShipmentDto PutShipment(
        Guid key, 
        Guid shipmentKey,
        ShipmentByAffiliateUpdateRequestModel requestModel,
        [BindShipment]Shipment shipment) {

        var updatedShipment = _shipmentService.UpdateShipment(
            requestModel.ToShipment(shipment));

        return updatedShipment.ToShipmentDto();
    }

    [EnsureShipmentOwnership]
    public HttpResponseMessage DeleteShipment(
        Guid key, 
        Guid shipmentKey,
        [BindShipment]Shipment shipment) {

        var operationResult = _shipmentService.RemoveShipment(shipment);

        if (!operationResult.IsSuccess) {

            return new HttpResponseMessage(HttpStatusCode.Conflict);
        }

        return new HttpResponseMessage(HttpStatusCode.NoContent);
    }
}

As said, I'd love to know how you handle these types of situations in your applications.