Thursday, November 22, 2012

Tag or untagged?

Fundamentally, there are only two different Ethernet switch port types: access or trunk.

An access switchport can only participate in the VLAN to which it has been assigned and data is not tagged.

A trunk switchport can participate in multiple VLANs but in order to do so expects the data to be 'tagged' so the switch will know where the data is ultimately expected to go. The switch then reads the VLAN ID tagged data and then knows to which ports it should be talking or where it should be going.

VLANs are typically used to provide logical separation for different network segments or subnets but it is important to realize that just because a switch supports layer-2 tagging (802.1q VLAN tagging) does not mean that it provides routing between them, which is a layer-3 function.

A trunk switchport would be employed if, for instance, your router supported trunking/tagging. Instead of simply being on VLAN 13, port 1 could be configured on the switch as a trunk port and both VLAN 13 and VLAN 459 would be set as tagged. Data from both networks could traverse the same physical wire back to your router but would not be aware of one another. Guests would still be isolated on VLAN 459 while the office was safe and sound on VLAN 13. Trunk switchports are typically employed in virtualization, where one network interface is expected to support systems on multiple VLAN IDs or network segments.

Tagged and untagged describe how a frame on a VLAN is transmitted from a port. The frame can be tagged in which case it will contains an 802.1q VLAN Tag Control information field, or not tagged. Untagged doesn't mean "not on a VLAN". In a VLAN-aware network, every packet is forwarded on a VLAN. In a VLAN-aware network frames need not contain a tag identifying the VLAN they are travelling on. Switches can use other mechanisms, such as policy to decide that.

VLAN is completely on wire side, wireless doesn't have this concept.

Tuesday, November 20, 2012

Design Pattern walkthrough

1. Proxy Pattern
- Proxy controls and manages access to the real subject.
- Same interface, so proxy can be substituted anywhere the subject can be used

  • Remote proxy: act as local represtative (RMI)
  • Virtual proxy: expensive to create, lazy initialization (Hibernate)
  • Transaction proxy: wire transactional support (Spring)
  • Security: protect


2. Command Pattern
- Encapsulate method invocation: store them, pass them around and invoke them when you need them
- It decouples the requester of an action from the oject that actually performs the action
  • Order a meal: order slip
  • Job queue: ControllerUpCmd, ApAddCmd
  • Device import: commands passed around and executed in context (e.g., session establish, error handling), acts like closure, function pointer. It is like Template method pattern, but instead of subclassing, the method is passed as command objects here



3.Strategy Pattern
- Defines a family algorithms, encapsulates each one and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it
- Encapsulates the behaviour, take what varies and "encapsulate" it so it won't affect the rest of your code




4.Observer Pattern
- Defines a one-to-many dependency between objects so that when one object (subject) changes state, all of its dependents (observers) are notified and updated automatically
- Subjects and observers are *loosely* coupled
- A key part in the familiar Model View Controller (MVC) pattern



 

Monday, November 19, 2012

Convention over Configuration (CoC)

Maven, Grail are examples of applying CoC. So do many modern framework. CoC essentially means a developer only needs to specify unconvertional aspects of the application. Only when the desired behavior "deviates" from the implemented convention is explict configuraiton required.

Comet & asychronous HTTP

Comet [1] is web application model to achieve "server push" or "reverse ajax".

Servlet 3.0 provides the asynchronlus support which allows the servelet request to be suspended and resumed, i.e., non-blocking, to avoid thread starvation.

HTTP persistent connection, also called HTTP keep-alive, is the idea of using a single TCP connection to send/recieve mulitple HTTP request/response. It is also controversial as that it may tie up server side thread for too long. And there is a related idea about HTTP pipelining in which multiple HTTP requests are sent on a single TCP connection without waitting for the corresponding responses.

Proxy server can be use to deal with cross-domains issue for hidden iframe and XMLHttpRequest, making them appears to originate from the same domain.

Monday, September 24, 2012

Passwork complexity check

String pattern = "^.*(?=.*[A-Za-z])(?=.*[0-9])(?=.*[\\W]).*$";
Zero-width positive lookahead assertion (?= some_expression) is used to make sure the password uses a mixture of letters, numbers and special characters.

Tuesday, June 19, 2012

Read-only transaction

As discussed earlier, for BE processing the pessimistic locking is adopted. The lock on mysql (select ... for update) is only released after transaction commits. This posts a challenge while there are multiple BE threads running and might easily get into dead lock situation.

To reduce the lock contention, I use the following approach: create new nested transaction to do the DB update, so only acquire/release lock in very short period time rather than holding it for the whole long transaction period (In my case, auditing). Note that the outer transaction need to be set to read only to avoid the flush completely, which is not just unnecessary but also failing because the object has older occVersion (Optimistic Concurrency Version). Although the outer and inner transactions have two different sessions, they are bound to the same thread, Hibernate will try to flush the objects in outer transaction right after the inner transaction commits.

// Or similarly, txTemplate.setReadOnly(true);
sessionFactory.getCurrentSession().setFlushMode(FlushMode.NEVER); 

// Simplify for testing, in the real world, we get the objects by a big query, and 
// running a bunch of things to determine whether the object need to be updated or not
final CoSTemplate ct = (CoSTemplate)templateDao.read(4);

TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);

txTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) { 
    // the object is reloaded from DB by getSession().refresh(tpl, LockMode.UPGRADE);
    CoSTemplate ct2 = (CoSTemplate)templateDao.lockRead(ct);
  
    History history = new History("something");
    ct2.addHistory(history);
    templateDao.update(ct2);
}
});

Wednesday, March 7, 2012

Resolve circular dependency in Spring

It is discussed clearly in Managing Circular Dependencies in Spring.

We used to deal with it in init() method. For example, A<->B, inject B into A, and in A's init(), call B.setA(this). This approach has two drawbacks. Not only the interface of B must expose an additional setA method; but also *this* refers to the raw instance of A, rather than a proxied (wrapped) instance of A. That means, if the method of A requires AOP proxy such as transaction interceptor, you will get Hibernate no session bounded exception. Remember, the Spring bean (applicationContext.getBean("xxx")) provides us both dependency injection and AOP proxy.

The article describes two solutions:
1. Inject ApplicationContext to one bean through ApplicationContextAware interface and look up the peer bean
2. Use a BeanPostProcessor to wire up the beans after they are instantiated. This is preferred since it allows the container to handle this, rather than the bean itself.

The implementation in the above post seems to be problematic. I always run into BeanCurrentlyInCreationException. I revised it as follows, basically, the passed in initialized bean should be target bean, and we know both beans are ready at this point. Also, I added support for proxy and factory bean.

<bean id="circularDependencyBeanPostProcessor" class="CircularDependencyBeanPostProcessor">
  <property name="config">
   <map>
    <entry key="templateManager">  
     <props>
      <prop key="policyDomainManager">templateManager</prop>  
     </props>
    </entry>
   </map>
  </property>
 </bean>
public Object postProcessAfterInitialization(Object targetBean, String beanName) {
  if (config == null) {
   return targetBean;
  }
  Map dependentConfig = (Map) config.get(beanName);
  if (dependentConfig != null) {
   try {
    if (targetBean instanceof FactoryBean) {
     targetBean = ((FactoryBean) targetBean).getObject();
    }
    
    for (Object sourceBeanName : dependentConfig.keySet()) {
     Object sourceBean = factory.getBean((String) sourceBeanName);
     
     // Jdk dynamic proxy is interface based, generally we don't want
     // to expose those set methods such as setPolicyDomainMgr()
     // in the interface. In this case, we inject the dependent bean
     // into its target object instead.
     if (AopUtils.isJdkDynamicProxy(sourceBean)) {
      sourceBean = ((Advised) sourceBean).getTargetSource().getTarget();
     }
     String propertyName = (String)dependentConfig.get(sourceBeanName);
    
     BeanInfo beanInfo = Introspector.getBeanInfo(sourceBean.getClass());
     PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
     if (propertyDescriptors != null) {
      for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
       if (propertyName.equals(propertyDescriptor.getName())) {
        Method setter = propertyDescriptor.getWriteMethod();
        setter.invoke(sourceBean, targetBean);
        break;
       }
      }
     }
    }

   } catch (IntrospectionException ie) {
    log.error("IntrospectionException", ie);
   } catch (Exception e) {
    log.error(e);
   }

  }
  return targetBean;
 }

Monday, February 6, 2012

UTF-8 encoding

On php UI, both fields (location, zone) support utf-8 characters. The user could type and save. What surprised me is that in mysql db, zone is defined as a varchar (latin1) column, and location is defined as a varchar (utf8). How can this work?

I set both zone and location to ‘测试’ and save. Below is the values stored in the DB. It is interesting that the zone field actually store the encoded utf8 string (each character takes 3 bytes) in a latin-1 column, whereas location field is a double encoded utf8 string which is unnecessary (it is because the connection setting is latin-1).

This is because the UI page uses utf-8 characters. It could be store blindly into a latin1 column.
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>

[Explanation for location]
The data is in utf8, the connection settings are in latin1. The table is in utf8. So, MySQL converts each of C3 and A9 (which it was told was latin1) to utf8, leading to 4 bytes in the table: C3 83 C2 A9. I call this double-encoding. The problem was caused by lying (usually accidentally) to MySQL about what encoding was in the application's data.

[Explanation for zone]
The data was loaded in an old system in the following manner. The application got utf8 bytes and blindly stored them in a latin1 column.

Reference: MySQL Charset/Collate