RSS

Monthly Archives: August 2014

Rock SOLID Code

Entry 12, Day 27

          You came back to me, good, good. As I’ve promised, this episode will be about SOLID. What’s that? It’s an acronym for five fundamental principles in object oriented programming coined in early 2000’s by Michael Feathers and Robert C. Martin (aka Uncle Bob). I’ve added Michael’s and Robert’s blogs in Places section, it’s highly recommended reading. Each principle is also covered by an article under “Read more” link. There are C++ examples, but it doesn’t really matter, ideas are valid for any statically typed language.

Now, let’s get down to business. Letters in SOLID stand for:

(S)ingle Responsibility Principle

          A class should have one, and only one, reason to change. Class should do one thing. Or broadly speaking, the context (method, class, package, module, etc.) should have a single responsibility and that responsibility should be encapsulated by this context. Why? Imagine a Read the rest of this entry »

 
5 Comments

Posted by on August 28, 2014 in Clean Code, Sweet Sixteen

 

Tags: , , , , ,

Legacy of the Void

Entry 11, Day 24

I’ve promised you episode on database, but I’ve lied. Okay, not exactly. Database was my plan, but I haven’t managed to play with the tools before leaving Wrocław for my short vacation. I’ve left behind my dev machine so let’s leave tools too for a week or two. But I’m not leaving you, dear reader.

Until now, I was mainly writing about enterprise stuff connected with my project. There are however many other topics I’d like to touch in this blog. One of them is Object Oriented Design. So today, for starters, since at the beginning there was nothing, I’m going to tell you about the Null Object, behavioural Design Pattern.

The definition says:

In object-oriented computer programming, a Null Object is an object with defined neutral (“null”) behaviour. Example:

nullobject1

Why bother? Because using Null Objects protects you from Null Pointer Exceptions and lets you get rid of ever-present null check logic in the code. So, instead of using null Animal references, you want to use NullAnimal objects. It will not throw NPE in your face, you don’t have to check if it’s there. It will just gracefully do nothing if interacted with. This is the classic – dedicated Null Object class, now let’s move to other, not so obvious usage.

Say you have some kind of state in the form of an enum. But sometimes the state is not present, or somehow unknown. You may use null for that, but you may also add an additional value – “UNKNOWN”, “NONE”, “SHIT_HAPPEND” or something like this. Usually cleaner and safer than null reference.

Third idea, if your object contains a collection, initialize it. Don’t rely on it being delivered via setter later. It is likely that the setter won’t be called, “because of reasons”. But if you put an empty collection at object creation, you are safe to iterate over it later, unless somebody explicitly sets null there, which is rather unlikely (you may also hide the setter itself if you like). There are situations where such practice turns out to be bad however. Be aware that empty collection has some size. It depends on system and VM implementation, but you can count from 40 bytes on ArrayList to around 70 on HashSet. Not much, but I had a case where graph node had several empty collections and when node numbers went into millions, there were corpses of virtual machines lying everywhere.

Finally, there is a nice class in Google Guava, the Optional<T>. It’s an immutable wrapper that can contain another object or null. It can return this object, or null or some default value. It can tell if there actually is an object, or not. It’s good, because you explicitly say that it’s okay to have null value here. The value is optional, as the class name says. Let’s see how it looks like in practice:

nullobject2

That’s about it. There are some issues to consider though. For example – Null Objects shouldn’t change their neutral behaviour. If they do, they actually belong to State Pattern. Null Objects may be special case of Strategy Pattern, representing strategy that well… does nothing.

There are also some caveats in Null Objects. Sometimes clean logic and lack of exceptions may hide erroneous program execution. So, for example, if you expect collection not to be empty, you should do some check before simply iterating over it zero times and move on in silence.

Project-wise, well… I’m proud owner of booksentry.org domain now, where you will find the application’s production environment in the future.

In the next episode, we will talk about SOLID code. Stay tuned.

Legacyof the Void

 
Leave a comment

Posted by on August 25, 2014 in BookSentry, Clean Code, Technology

 

Tags: ,

Into the Wild

Entry 10, Day 20

Time to talk a little environment. Go green, plant a tree, that kind of stuff. Kidding. We are going to talk about the server and the data source for the application. First, what is actually a server?

Server in general is something (hardware + software) that provides responses for requests across the network (or even locally). We are mainly interested in web servers, so we have a http request and http response. This doesn’t actually narrow down to www. They are WebServices carried over http via SOAP. You know, machine talking to another machine, skipping the unreliable protein-based components. Since I’m a programmer, not a sysadmin, by the term server I will understand the software part.

There are basically 3 tiers of server, we would be interested in:

HTTP Server. This is basically just to serve static resources, including client side scripting languages. You can build quite a big piece of an application in GWT, and as long as it does not require any server side dynamic behaviour (say database access), you are good. But who doesn’t require database access those times? The unbeatable king of http servers is the Apache HTTP server. The piece of software that gave name to the entire organisation later. Before Java settled in the web, we would just take Perl or PHP, put it somewhere around Apache, lay hands on database, or whatever is needed and be happy. But now we have…

Web Container. It is more than http server, since it implements a tiny but important part of Java Enterprise Edition api. Namely Servlet and JSP. Those seem to be a bit outdated technologies, but they are a basis for every new and fancy stuff in Java web world. For example, Spring is actually a big servlet underneath. Again, there is a clear leader in this field, Apache Tomcat. But what, if you need more?

Application Server. The monstrosity that implements entire JEE specification. So, besides what web container offers, we have JSF, persistence, transactions, messaging, batch api and other stuff, but perhaps most notably: the Enterprise Java Beans. There quite a few application servers out in the field. I’ve worked with Weblogic and Glassfish. If you don’t like Oracle, there is also JBoss (it is called WildFly now, as I’ve just learned). Or Apache Geronimo for anarchists.

So, what do I actually need? Since I’m going to use Spring, and Spring has many features that replaces JEE standard (Actually many apis in modern JEE were inspired by Spring.), I’m not going to need full application server. Web Container is enough for Spring, so it should be enough for me. Since picking up a popular server simplifies hosting and development in general (lots of people have the same problem as you) I’ll go with Tomcat 8.0.9. If there would be a need for an application server in the future, we are going to have a migration. Shouldn’t be tough, should it?

And what about database? I have serious time issues recently, so in order not to keep this post too long in the draft state, we will talk this through in the next episode. Stay tuned.

Project-wise, I’ve set up Tomcat, created a project draft, installed MySQL and did some smoke test displaying stuff from the database via simple servlet. Nothing fancy, just hellowording. Now I’m looking for some nice MySQL client besides command line :) Any suggestions?

How-To-Train-Your-Dragon-2-Wallpapers-23

 
1 Comment

Posted by on August 21, 2014 in BookSentry, Technology

 

Tags: , , ,

The First Artifact

Entry 9, Day 16

     “The product backlog is an ordered list of everything that might be needed in the product and is the single source of requirements for any changes to be made to the product.”

– Scrum Guide

Being recently in the tools department, let’s continue the topic and look for something to manage The Product Backlog.  But wait, what’s that?

As I’ve said, I’m not going to do full fledged Scrum here, because there is no point in that. However I will keep some of Scrum elements. For example, Scrum defines so called Artifacts. There is the Product Backlog, there is a Sprint Backlog and there is an Increment. I’ll keep the Product Backlog. I will probably not need Sprint Backlog. And we will see about Increments later.

So, the Product Backlog (or simply the Backlog from now henceforth) is where the idea of the product is kept. The idea might be more or less clearly and precisely defined, usually the higher the priority, the better the definition. The Backlog is composed of Items. Single Item might be a requirement, feature, enhancement, bugfix or anything that is going to change the product. Changes may be indirect and be without immediate value, say “Setup Tomcat” is actually an internal task, but it is required to proceed for me.

My needs are simple. I need a tool where I can add items in at least three categories – to do, ongoing and done. I need to be able to easily change priority (distance from top of the list), move between categories (say it’s ongoing / done) and edit Items. The tool should be cloud based (fancy term recently), free and publicly accessible.

In my work, we have mostly used Excel with quite advanced scripting (hi Kamil ;)) to help with moving, changing and calculating stuff. Sometimes we would just take a pin board and stick notes to it (It is common with Sprint Backlog, but not really with Product Backlog). Or simply there was no public Backlog whatsoever (well…).

But Excel has drawbacks. First, it is a desktop tool, and I want to share stuff in the blink of an eye. So, I could go for Google Spreadsheets, but still manipulating Items would require some effort. Let’s look for something more dedicated then. Quick research convinced me that there is an overwhelming number of tools to choose from. You can check out Wikipedia’s comparison of project management tools, You can then narrow the criteria to Agile tools. I’ve taken a look here and there. I’ve decided to give some of them a try.

So first, there is Jira. It was used by some teams around me. But apparently, it is not free, and is too big for my needs. We need simplicity. Out.

Someone mentioned Any.do when I was sniffing around. Unfortunately, while it’s simple, it’s also more of a calendar tool, not really good for me. Out.

Then, there are quite a few tools (I’ve checked iceScrum), that are open source, but there is no free hosting. Either you download and host by yourself or you pay. I want it quick, I want it now, I want it free. And I don’t have a hosting department operational yet. Out.

There are also promising tools closed source, but they are paid (e.g. Agilo for Scrum). Well, out.

There was one tool that was free and looked nice. The AgileFant.  I’ve played with it a bit, but it turns out to be too cumbersome for me. There were some UI glitches and manipulating items was not that simple as I wanted. Still it might be a valid option for fully Scrum team.

And finally there was Trello. Few friends actually recommended me this and it turns out to be perfect for my needs. It’s simple, intuitive, adorable and it is flying free above the clouds. As a welcome, you get three boards: to do, doing and done. You can quickly add Items, move vertically and horizontally, edit, add categories and make the board public. I’m not going to give you full review, that’s not what I’m here for. But you may want to check article here. The Wired had an article about coolest 7 startups you haven’t heard of, and Trello was one of them.

So, I have a lingering Product Backlog. You may check it out here. The link will be always available from the BookSentry, the main project page.

Huh, that was a long one. In the next episode, I’m going to talk about the environment. Namely the Server and the Database.

p.s. I’m using Wikipedia links a lot. It’s not because I’m a noob. My intent is to give you some quick and neutral overview of the subject at hand. You can get easily to subject’s home page (if it has any) from Wikipedia page for further, official details.

dragon2-4

 
1 Comment

Posted by on August 17, 2014 in Agile, BookSentry

 

Tags: , , ,

Tools of the Trade

Entry 8, Day 14

Over ten years ago I have written my home page in PHP. Nothing really big, but it had a user system, administration, news, comments, file downloads, image gallery with some search/paging options, rating etc. I think there was around 100 – 200kB of code. I did this almost entirely in Windows notepad, only at the end switching to some kind of editor with html syntax highlighting. But things can be done easier.

First, you need an integrated development environment. I will use Eclipse Luna, released not even two months ago. I’m using Eclipse for over five years and still learning new stuff on a weekly basis. Alternatives are: InteliJ, NetBeans or something else.

When dealing with web application, there are several useful tools on the browser side. First, the browser itself and it’s integrated development tools, at you disposal when dealing with html, css and client side scripting problems. My favourite is Firefox. When browser tools are not enough, I recommend Firebug, excellent for debugging JavaScript if you are in a pitiful situation that you need to do that (you shouldn’t if you use GWT, but…). In order to work with GWT efficiently, you need DevMode, it will compile your Java code to JavaScipt on the fly and allow to see changes almost instantly, Yo will need a plugin for Eclipse and a plugin for your browser to accomplish this. Unfortunately since Firefox 27, support for DevMode has ended (wtf dudes?), so either stay at 26 or try some workaround.

Compiling, putting into jars, bundling etc. – Maven is your friend here. If you are old school, get back to Ant.

When you write something and it works, or even before it does, you are in need of some version control system. As of my information, Git recently took over SVN in terms of popularity. Also, I’ve worked long enough under SVN, so lets try something different. Git it is.

Having a build automation and version control, you can put them together in continuous integration tool. It will take the code each time someone does commit and each night, build stuff and scream at you if you blew something. Jenkins is probably the best choice here. You may know it’s older version, Hudson, which killed itself after being taken over by Oracle.

There are plenty of additions to CI, most of them also available as IDE plugins.

Most notably, test automations frameworks. Unit tests for low level stuff (go JUnit with Mockito) and web/GUI tests for high level/integration (Selenium being a popular choice).

It is good to have some kind of static code analysis. Teach it a set of rules, and it will guard your code from deteriorating at low level and perhaps find some bugs for you, that might have slipped through runtime test suite. Check out FindBugs. For higher level of analysis I recommend SonarQube (known simply as Sonar in the old days). It will also give you a bunch of numbers about your codebase, if you like numbers. I like numbers.

There are plenty other useful stuff for your CI, e.g. some dashboard view, excellent to de displayed somewhere high on the wall, to tell others that your build is never broken. Or to tell you that it actually is now and it would be nice to fix it. You may also want to hear this.

Besides development, you want to keep track of what is to be done, ongoing and done. So basically a product and a sprint backlog. Until now I’ve used mostly simple Excel and physical pin board, I need to do some research here and get back to it.

Also there are systems for issues tracking (fancy term for bugs), which may be used instead of, or with backlogs to help you control your chaos. (Hi Kate ;))

Pedal_control

 
2 Comments

Posted by on August 15, 2014 in BookSentry, Technology

 

Tags:

Here be dragons

Entry 7, Day 11

It seems that I’m more of a writer than a coder in this little endeavour. Well, old habits die hard, I wrote quite a lot of stuff several years ago, although not really technical. Anyway, this is good. Before you sit to code in the new projects, there are some stuff, you need to discuss with other devs, the Product Owner, Stakeholders/Clients, right? (Yes, devs can talk to Stakeholders directly, even though the PO is their default world interface. It can be very beneficial to the project). So now, let’s wander into the unknown lands of dragons. The enterprise (and less enterprise) technologies. There will be a lot of links.

Usually, there is a number of so called “technologies”, you will want to use. Theoretically, you can write an application using almost pure Java on top of application server (or what the hell, even without the server, just play with sockets manually), but it is impractical to say the least.

Under normal circumstances, the technology choice depends on what you want to achieve, what are the skills in the team at your disposals or other external factors like deals with big nasty software corporations. Since I’m my own client, I’m free to do what I please. I will go for some healthy mix of things that are suitable, fun, that I want to learn, and that I already know, and want to know better. Using only unknown technologies might be more beneficial from the learning point of view, but being struck at every aspect of the application might not be funny (not that I’m a pessimist, but I’ve seen stuff…). So I need some fields, where I know I can go fast to repair my ego if needed.

So, the main technology I will use is Java 8 language, as I’ve mentioned in the previous post.

Of course, since we are talking web application, the backbone of everything is HTML, this is what the user receives at the end.

There must be some kind of presentation technology (unless you are writing some purely backend EDI system or something similar). If you are truly old school, you can go with JSP pages. A bit more modern approach would be JSF or Velocity. There are plenty fish in the sea.

Client likes the application to be responsive. So instead of reloading the entire page, you can do things in the browser, instead of on the server. We can go with JavaScript, Dart, or my favourite: GWT. Actually GWT will do the job with both static and dynamic web content, and it is a Java compiled to JavaScript. I’m a big fan.

Then there is (usually) the framework that simplifies things (or complicates, depending on the framework and usage). Spring is the choice here, since it’s tremendous popularity in recent times. I’ve used it quite a bit, but there is still much to learn for me.

There is an object-relational mapping framework, Hibernate being popular choice.

Those are the core technologies. There will probably be many more, but we are not doing Big Design Up Front, remember? I will add and comment on new stuff as needed.

By the way, I think the word technology is sometimes an overkill when it comes to software. Nuclear bomb is a technology. Internal combustion engine is a technology. Microprocessor is a technology. Although Wikipedia says that technology is “collection of tools, including machinery, modifications, arrangements and procedures used by humans”, it seems to me that a piece of software written by a guy over several evenings while drinking beer shouldn’t be called that. Not that I don’t respect contribution to mankind well being, but there is a matter of scale. Probably “library” is sometimes a better word than “technology”.

dragons

 

 
Leave a comment

Posted by on August 12, 2014 in BookSentry, Technology

 

Tags: , , ,

The Peak of the Mountain

Entry 6, Day 10

The technology stack… We’ve talked a bit about tiered application composition, now let’s take a broader look. Software is basically composed of layers. That simplifies things. You have an operating system using hardware directly. Then, there is the Java runtime providing abstraction between Java bytecode and actual program execution. Then, if we are in the JEE realm, we have a server.

The kind of server depends on you needs. If you like EJBs, you need an application server (Weblogic, Glassfish or whatever). If you prefersomething lighter, you can go with web container (like Tomcat). Finally to help you serve static content like Java Script (which is static in terms of being executed on client machine, not ours), there are http servers like Apache. You can combine all of them – use application for EJB layer, web container for web layer and http for static. There might be, of course, many more servers in the application ecosystem, namely proxies, firewalls, load balancers (or it can be dedicated hardware, and usually is), but this is more of the infrastructure domain, not application.

Then there is some kind of framework providing abstraction over JEE api or just complementing it. Think Spring.

And, at the peek of the mountain, there is Java language. The language shapes architecture of your system, ties things together and allows you to play with stuff. I’ll go with Java 8 because well… cutting edge, you recall, do you?

Actually Java 8 is quite cool. Everyone says that’s because finally we have lambda expressions, but there is more. There is, for example, internal iteration.

Internal iteration, instead of imperatively iterate over collection, allows you to declare iteration and let the runtime do the rest. Why it is important, you may ask? Because if you iterate imperatively you do that either in sequential way, or you have to play with threads, think about number of available cores and do other tedious and error prone stuff. If you let the runtime iterate, on the other hand, it may perform e.g. a new forEach operation concurrently, using all available cores, and this is transparent for you. It makes things simple and fast.  Also, a new Stram api allow you to perform map, filter, reduce, and other operations with performance improved by doing what really must be done lazily. I haven’t yet explored all new features of Java 8, but things look promising.

<scary JVM internal stuff>

By the way, lambdas aren’t just syntactic sugar for inner classes as many people think. In fact, lambdas implementation in virtual machine uses additional layer of abstraction. Lambda is actually a recipe, not an imperative piece of bytecode. It’s true bytecode is generated on runtime, not compile time, using fifth invocation mode, invokedynamic, introduced in Java SE7 to support dynamic JVM languages (Groovy, Jython etc.). Lambda call site is created using so called “language logic” or “bootstrap method” that was to be provided by specific dynamic JVM language to help dispatch calls. In Java language lambdas execution, such logic is called Lambda Metafactory.

As a result of several nifty VM tricks, lambdas are much faster than inner classes, especially on multicore systems, and have a potential to be even faster in further versions of Java. If you are into this stuff, check out a cool presentation by Brian Goetz, the Java language architect.

</scary JVM internal stuff>

So, I’m going to use Java 8. And few other runtime technologies, which I will discuss in the next post.

top of the mountain

 
1 Comment

Posted by on August 11, 2014 in BookSentry, Technology

 

Tags:

The Matrix

Entry 5, Day 8

The first matrix I designed was quite naturally perfect. It was a work of art. Flawless. Sublime. A triumph only equaled by its monumental failure.

– The Architect

Software Architecture is the high level structure of a software system. Now I’m smart, I have Wikipedia.

Sometimes, if you ask a developer what is the architecture of the system he is working on, he would say something like, “Well, we have a JSP view, we use EJB to figure things out, Hibernate to persist and everything sits on top of Weblogic server”. Actually, this is not an architecture description, this is a list of technologies used to create the system (or, if you need a fancy term: the technology stack). Of course, there is a slight hint, that we are dealing with a client – server application with at least three layers.

Architecture might be client – server, peer to peer, event driven, rule based, plug-in based or other. Or the combination of them.

As I said before, I’m aiming for agile, emergent design. It does not imply, that I don’t have some kind of vision of what I want to write. I will probably go with client – server, multi tier application. What does this mean? We know more or less, what is 3 – tier architecture: we have a Presentation layer, Business Logic layer and Data layer. So where is the fourth and fifth or any further layers? Well, you may divide those layers further. Let’s take a look.

Presentation is well… presentation. But if you go beyond simple CRUD, it might turn out, that you need some kind of logic just for managing presentation (fancy drag n drop and dynamic stuff support for example), not really business logic layer, but layer separate from static HTML inputs. So, you may split this into two.

Business Logic might have controllers, which glues together front end and back end. And then, they might have EJBs or Spring Services, which performs actual computations or choices having data and given user input. Or other input for that matter, say JMS messages or WebServices calls from foreign systems. Also, you may split service in as many layers as you need depending on the case. Some systems might be very sophisticated, and saying that there is just one business logic layer would not be an understatement.

Data layer may consists of Data Access Objects, which gives you data in the form of cute little Java objects magically drawn from the database. Then there is the magical Object Relational Mapping Framework at work, preparing and running queries in SQL native to the database, transparently for the user. Database is the, more or less, final layer, and besides table definition it may consists of triggers, scheduled jobs (for partitioned tables periodic cleanup, for example) and some other nasty things. Perhaps there are also other layers in the database department, but well… I’m more like in the Java department, so I won’t dig deep here.

Some developers shun the idea of doing any logic outside of Java code (I’m not talking about external libraries, but I will later). I was such developer once. But I’ve figured out, that some things may be better done outside of Java, even though I cannot put a breakpoint there. I’d love to think about them as Java minions who do some magic yet inferior things, but as long as they do it well, I have no objections. Otherwise I will have to frown my eyebrows, get out of coziness of my beloved Eclipse and step in to figure out why SQL or ant script is behaving badly.

 

vsbigone

 

 
Leave a comment

Posted by on August 9, 2014 in BookSentry, Clean Code, Technology

 

Tags: , , ,

The Approach

Entry 4, Day 6

A lot of work in documentation and social media department. I’ve split the About page into three separate ones and add some content to them, and organize widgets..

But lets get back to the project.

We are going to talk a little about general approach to writing software. There are two basic ideas you can follow:

Big Design Up Front – Spent a lot of time gathering requirements for the entire application, carefully plan the architecture amongst white-bearded gang of architect, proceed to code and then test the application. At the end most of the requirements will be outdated since Client will figure out that he wanted something entirely else. Or go bankrupt in the middle of entire process. You are left with beautifully designed and mostly useless software.

Emergent Design – Also known by some coder as Pile of garbage. Actually this is the case if you do it wrong, because emergent design does not mean that we add and add and add new features without any clue or second thoughts. We add new features incrementally within some short periods of time like two weeks (called Sprints). We land with with business value, and working software, go to the Client and ask, “is this what you wanted?”. If it wasn’t, we have two wasted weeks worst case and a lot of experience. However if the Client is happy, we get back to keyboards, seek for common points and patterns and refactor to shape the application structure. We can do that safely, because we have a suite of automatic tests that will protect us from bugs, do we?

Actually, the way to go depends a bit on situation. Some projects may have a very strict and stable requirements, and it might be efficient to use BDUF at the end. But I thing those are in minority. Most of the time you don’t know what will happen in the future. If you do however have a good vision of how the application will look like, It might help you make better choices and plan a bit in advance, saving here and there. Not an easy task, but who said that software development is easy?

I will go with almost pure Emergent Design, and hope it will not turn into, well.. you know.

approach

 
Leave a comment

Posted by on August 7, 2014 in Agile, BookSentry

 

Tags:

Dramatis Personae

Entry 3, Day 4

Before an application is created, we need people to do that. People assume different roles, and I’ll try to define them today.

I thought, I will be using SCRUM framework, but actually by definition you can’t have SCRUM if you have only one person (unless we are talking split personality or other mental disorder). As you may know, Scrum Master and Product owner cant be the same person because of conflict of interests. However lets forget about that for a moment and take a look:

Client – The guy with money, needs and usually little to no idea how exactly to fulfill those needs with proper software. He wants stuff done quickly, cheaply and with high quality and finds it hard to understand that he has to pick one of those three. Usually does nor understand technology and people creating it.

Product Owner – This is the guy that is patient enough to talk to Client without cutting himself. He is able to find out what actually Client needs, what is most important for him and translates this into prioritized User Stories. Then he comes to the Dev Team and tries to explain what needs to be done to make Client happy.

Dev Team – Bunch of guys who talk strangely, gather in circle and sacrifice coffee to summon and control software. At least that’s how it looks like from the Client point of view. Dev Team has all the skills, resources and pizza required to create an Increment – working piece of software that can be thrown at production servers and will not cause a disaster. Or at least not a big one, small to medium seems to be tolerated on most circumstances.

Scrum Master – Invisible ninja who makes sure the other three do not kill each other. Basically knows the Scrum Grimoire by heart and guards the entire process not to go bananas. Should also has a healthy amount of common sense and transfer some of it to relevant party if needed.

So, I am going to be the Client, the Product Owner, the Dev Team and the Scrum Master in one person.

Besides talking (writing) a lot I’ve done a bit of investigation in hosting department. Nothing special.

 

How-to-Train-Your-Dragon-2-Hiccup-Toothless

 
3 Comments

Posted by on August 5, 2014 in Agile, BookSentry

 

Tags: , , , ,