Author: dicksonkho
Microsoft Free Ebook
For those who are Microsoft fans, here you go…
Our Iceberg is Melting
Accidentally found this book in company library, and was attracted by cartoon cover (personally not so interested in those business related book).
Finished it in half a day time with my breakfast and a cup of coffee…
Jot down some key value here for sharing.
- Create a sense of urgency
- Pull together the guiding team
- Develop the change vision & strategy
- Communicate for understanding buy in
- Empower other to act
- Produce short-term wins
- Don’t let up
- Create a new culture
p/s: Very informative book which not merely talking about business or management, but also telling the fact which happen around us (in a fable way) and how can we tackle that.
Found the short video clip for the book @ [Leadership/Business] John Kotter
Cyberjaya Sunset
25-05-2015
18-06-2015
Mobile is changing the world
Mobile: It Changes Everything from a16z
Beware when import cordova.js
If you would like to trigger the “deviceready” event fires when Cordova is fully loaded for some plugin usage,
document.addEventListener("deviceready", callbackFunction, false);
you need to include cordova.js in your application.
<script type="text/javascript" src="cordova.js"></script>
OK, you are done.
If you facing some unknown error in console as below even you have whitelist plugin added, cordova.js included,
Uncaught Error: Module cordova-plugin-whitelist.whitelist does not exist. cordova.js:891 deviceready has not fired after 5 seconds. cordova.js:884 Channel not fired: onPluginsReady cordova.js:884 Channel not fired: onCordovaReady
then probably you include cordova.js wrongly as what I did (get from /platforms/android/assets/www/cordova.js)
<script src="asset/js/cordova.js"></script>
NOTE: You does not need to copy cordova.js from anywhere, just include as above mention will do, Cordova will figure out for u 🙂
Having pbcopy and pbpaste in Cygwin
Just add these 2 lines in your .bashrc
alias pbcopy="cat >/dev/clipboard" alias pbpaste="cat /dev/clipboard"
We can now copy text into clipboard by piping it to pbcopy
# Copy current path pwd | pbcopy # Copy current datetime date | pbcopy
And paste it from clipboard by pbpaste
# Paste it to new file pbpaste > path.txt # Paste it to terminal pbpaste
Sportify Engineering Culture
They divided team members into focus autonomy squads who involve in full development cycle from implementation, deployment till maintenance for a system.
This not only increase the level of collaboration but also decrease the level of dependency to other teams.
They practicing release small and frequent which allows to spot integration problem early and invest heavily on automation test.
They believe in fail fast, learn fast, and improve fast.
Bad thing might happen unconsciously, instead of finding who is the culprit, fix it and learn from it will be the better spirit.
Healthy culture heals broken process, and healthy culture does not come easily, it need time, collaboration, trust…
OK… lets watch the video without further ado 🙂
Source : https://labs.spotify.com/
Sekinchan-17-05-2015











SpringData for MongoDB
Since there are numbers of tutorial out there to teach you how you can get simple MongoDB application up and running with spring data, so I’m not going to talk about it here, instead try to summarize Spring Data for MongoDB (v1.7) after reading it 🙂
Generally there are 2 way to perform tasks against MongoDB using SDMB (Spring Data MonggoDB) describe below:
1. MongoTemplate
Code snipped below show how easy we can insert, find and drop a collection in MongoDB using MongoTemplate.
@Document
public class Shop {
@Id
private BigInteger id;
private String shopName;
private String address;
public Shop() {}
public Shop(String shopName, String address) {
this.shopName = shopName;
this.address = address;
}
public BigInteger getId() {
return id;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getShopName() {
return shopName;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
}
@Configuration
@EnableMongoRepositories({"com.dicksonkho.repositories"})
public class MongoConfig extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "shopdb";
}
@Bean
@Override
public Mongo mongo() throws Exception {
return new MongoClient("localhost");
}
@Override
protected String getMappingBasePackage() {
return "com.dicksonkho.domain";
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MongoConfig.class})
public class TemplateTest {
@Autowired
MongoOperations mongoOperation;
@Test
public void testCRUDRecordWithTemplate() {
Shop shop = new Shop("muimui", "Taming Jaya");
mongoOperation.save(shop);
Assert.assertNotNull(shop.getId());
Shop insertedShop = mongoOperation.findOne(new Query(where("shopName").is("muimui")), Shop.class);
Assert.assertEquals(shop.getId(), insertedShop.getId());
insertedShop.setShopName("newmui");
mongoOperation.save(insertedShop);
Shop updatedShop = mongoOperation.findOne(new Query(where("shopName").is("newmui")), Shop.class);
Assert.assertEquals(shop.getId(), updatedShop.getId());
mongoOperation.dropCollection("shop");
}
}
NOTE : MongoTemplate implements MongoOperations
- When we insert new Post, MappingMongoConverter (default for MongoTemplate) will do the class / object type mapping, and save into MongoDB.
- There are numbers of methods provided in MongoTemplate to deal with MongoDB, such as upsert, count, findAndModify etc.
- It supported geospatial, GeoJson, and full text search queries.
- It support map reduce operation to perform batch processing and data aggregation.
- It provides methods for managing indexed and collection.
- We can execute MongoDB driver’s DB.command using executeCommand and any exception will translate into Spring’s DataAccessException hierarchy.
2. Repository
There is a core marker interface for Spring Data repository abstraction called Repository, which then inherited by few sub-interface sort in hierarchical order as below:
Repository < CrudRepository < PagingAndSortingRepository < MongoRepository
Defining a query to manipulate data just a matter of declaring query method on repository interface.
Refer sample interface below, we will have a method for querying shop by shop name, querying shop name which start with some regex pattern, etc.
public interface ShopRepository extends Repository<Shop, BigInteger> {
Shop save(Shop shop);
Shop findByShopName(String shopName);
Shop findOne(BigInteger id);
Shop findByShopNameStartingWith(String shopName);
List deleteByShopName(String shopName);
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MongoConfig.class})
public class RepositoryTest {
@Autowired
private ShopRepository repository;
@Test
public void testCRUDRecordWithRepository() {
Shop shop = new Shop("muimui", "Taming Jaya");
repository.save(shop);
Assert.assertNotNull(shop.getId());
Shop shopByShopName = repository.findByShopName("muimui");
Assert.assertEquals(shop.getId(), shopByShopName.getId());
Shop shopByNameStartWith = repository.findByShopNameStartingWith("mui");
Assert.assertEquals(shop.getId(), shopByNameStartWith.getId());
List & lt;Shop & gt;
deletedShopList = repository.deleteByShopName("muimui");
Assert.assertEquals(1, deletedShopList.size()); // 1 record deleted
Shop recheckTheShop = repository.findByShopName("muimui");
Assert.assertNull(recheckTheShop);
}
}
NOTE: Sample above extends the most basic Repository interface, but we can extends other interface like CrudRepository, PagingAndSortingRepository based on our need.
- There are 3 types of query lookup strategies being use by Repository infrastructure:
CREATE, USE_DECLARE_QUERY and CREATE_IF_NOT_FOUND (default) - There are numbers of method convention are available such as: findByXXXLessThan, findByYYYBefore, findByLocationNear, etc.
- We can also create MongoDB JSON based query method to override the query method as sample below:
@Query("{ 'shopName' : ?0 }") List<Person> findByShopName(String shopName); - Result of query can be process incrementally using Java8 Stream as return type.
- Support integration with QueryDSL to provide type-safe query.
- Support full text search.
Spring Data extensions (Web Support)
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@EnableMongoRepositories({"com.dicksonkho.repositories"})
@ComponentScan(basePackages = {"com.dicksonkho.controller"})
public class MongoWebConfig extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "shopdb";
}
@Bean
@Override
public Mongo mongo() throws Exception {
return new MongoClient("localhost");
}
}
As you may notice, these configuration was exactly same as MongoConfig except 2 additional annotation (EnableWebMvc & EnableSpringDataWebSupport) which to enable spring data web support.
@Controller
@RequestMapping("/shop")
public class ShopController {
@ResponseBody
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Shop showUserForm(@PathVariable("id") Shop shop) {
return shop;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MongoWebConfig.class})
@WebAppConfiguration
public class SpringDataWebSupportTests {
private MockMvc mockMvc;
ObjectMapper mapper = new ObjectMapper();
@Autowired
protected WebApplicationContext webApplicationContext;
@Autowired
private ShopRepository repository;
@Test
public void getShopWithWebSupport() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
Shop shop = new Shop("muimui", "Taming Jaya");
repository.save(shop);
MvcResult result = mockMvc.perform(get("/shop/" + shop.getId())).andReturn();
Shop shopResponse = mapper.readValue(result.getResponse().getContentAsString(), Shop.class);
Assert.assertEquals("Taming Jaya", shopResponse.getAddress());
repository.deleteByShopName("muimui");
}
}
See, we just need to pass in id as request parameter, and we get back the object without any additional coding. What it does was internally convert the path variable and access the instance through findOne() on repository instance.
Besides that, spring data web support able to resolve request parameter (page, size and sort) to Pageable instance which then allow us to use it to query list of object with pagination and sortable functionality (refer snippet below).
@RequestMappingpublic String showUsers(Pageable pageable) {
...
}
Lifecycle Events
There are few lifecycle event allow us to intercept an object before/after certain action take place.
public class BeforeConvertListener extends AbstractMongoEventListener {
@Override
public void onBeforeConvert(Shop s) {
//change the state of object, or whatever
}
}
public class BeforeSaveListener extends AbstractMongoEventListener {
@Override
public void onBeforeSave(Shop s, DBObject dbo) {
// change the state of object, or whatever
}
}
Reference : Spring Data MongoDB – Reference Documentation
Source code available @ github









