środa, 13 grudnia 2017

bash - how to concatenate array with given delimiter

Let's declare array
 a=(aa bb cc) 
Now we can display the content with
$echo ${a[@]}
aa bb cc
First, give some naive solutions a try
$for el in ${a[@]}; do echo -n ,$el; done
,aa,bb,cc
$printf ",%s" ${a[@]}
,aa,bb,cc
Both work well, right? Hmm.. almost.

The last thing to do is get rid of the first comma

$for ab in ${a[@]}; do echo -n ,${ab}; done | cut -c2-
aa,bb,cc

wtorek, 21 listopada 2017

Why Spring returns 404 for my request?

When Spring Web MVC returns 404 in response to our request it means that cannot find handler for request "signature". As a signature we mean request mapping and request parameters.

How Spring resolves handler for a given url address?

The class responsible for matching mappings with requests is org.springframework.web.servlet.DispatcherServlet. The specific handler will be determined by applying handler mappings. Method responsible for that is called getHandler and it takes HTTP servlet request (Good old javax.servlet.http.HttpServletRequest instance). It basically goes through all registered handler mappings and tests each in order. The first match win. As the result, it returns an object of HandlerExecutionChain class.
AbstractHandlerMethodMapping.java

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {..}

Resolving details

At first, it looks for a direct match. eg /api/logs/3/4 Next, it starts to look for matching patterned paths eg. /api/logs/{parent}/{child}. Takes all matched and is looking for the best match.

niedziela, 12 listopada 2017

package org.maziarz.ldap;

import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.spi.DirObjectFactory;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.AuthenticationSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

public class LdapTemplateTest {

	private static LdapProperties ldapProperties = new LdapProperties(
			"ldap://:389"
			,"LdapUser"
			,"s3cr3t"
			,"DC=mycompany,DC=local"
	);


	@Autowired
	private LdapTemplate ldapTemplate;

	public static class MyDirObjectFactory implements DirObjectFactory {

		@Override
		public Object getObjectInstance(Object o, Name name, Context context, Hashtable hashtable, Attributes attributes)
				throws Exception {
			return new InitialDirContext(ldapProperties.getContextProperties());
		}

		@Override
		public Object getObjectInstance(Object o, Name name, Context context, Hashtable hashtable) throws Exception {
			return new InitialDirContext(ldapProperties.getContextProperties());
		}
	}


	@Before
	public void before() {

			LdapContextSource ldapContextSource = new LdapContextSource();
			ldapContextSource.setUrl("ldap://"+ldapProperties.getHost()+":"+ldapProperties.getPort());
			ldapContextSource.setBase(ldapProperties.getContext());
			ldapContextSource.setUserDn(ldapProperties.getUsername());
			ldapContextSource.setPassword(ldapProperties.getPassword());

			ldapContextSource.setDirObjectFactory(MyDirObjectFactory.class);

			ldapContextSource.setAuthenticationSource(new AuthenticationSource() {
				@Override
				public String getPrincipal() {
					return ldapProperties.getUsername();
				}

				@Override
				public String getCredentials() {
					return ldapProperties.getPassword();
				}
			});

			ldapContextSource.afterPropertiesSet();

			ldapTemplate =  new LdapTemplate(ldapContextSource);

			ldapTemplate.setDefaultCountLimit(1000);
//			ldapTemplate.setIgnorePartialResultException(true);
	}


	@Test
	public void fetchAllAccounts() {

		List search = ldapTemplate.search(
				"OU=Users,OU=COMPANY", " (objectClass=person)",
				(AttributesMapper) attrs -> {
					if (attrs != null && attrs.get("sAMAccountName") != null) {
						return Arrays.asList(
								attrs.get("sAMAccountName").get()
								,((attrs.get("sn") != null)? attrs.get("sn"):"none")
						);
					}
					return "";
				});

		System.out.println(search);

	}


}

sobota, 14 października 2017

Watchman - How to automatically copy modified files to the docker container

Watchman package is a really great tool but requires a while to understand its magic. To install it just type
$ brew install watchman
In 4.9 version it comes with three commands:
  • watchman
  • watchman-wait
  • watchman-make

The latter two are just utilities under the first one.

Lets focus on watchman itself and one of its outstanding feature called triggers. Actually, it is what it sounds to be - a mechanism that causes invoking given action on a given event happened (for example copying file to the remote server once it appear in certain folder)

Watchman Trigger Examples

Copying js files
 watchman -- trigger $PWD cr '**/*.js' '**/*.css' '**/*.html' '**/*.php' -- sh push.sh
Which basically causes all js, css, html and php files from the current folder are passed to push.sh script.

Push.sh script can look like this:

for i in $@
do
 docker cp $i centrum:/var/www/html/$i
done

poniedziałek, 3 lipca 2017

docker "/usr/bin/env: bad interpreter: Text file busy"

Today I faced the following error while trying to init my docker container.

Here you are the content of the script running as a part of the entrypoint commands chain

!#/usr/bin/env bash

chmod +x /my-script.sh && /my-script.sh run
It seems that the /my-script.sh file modification is still ongoing whilst we try to run it. The solution is to force system to flush buffers before using the file. Sync command is what we need.
!#/usr/bin/env bash

chmod +x /my-script.sh && sync && /my-script.sh run

poniedziałek, 15 maja 2017

Angular 2 - Declarative forms

Angular comes with a little bit bloated way of creating forms. Creating each field manually definitely give us full control of how particular fields will look, but on the other hand if there are more then couple fields it is terribly tedious. Moreover, any change requires visiting all places given ux pattern is used (eg. displaying validation errors, labels, etc.)). The declarative way of defining such forms seems to be ideal solution.. but there is no such out of the box.. It's sad.

Luckily Angular with its expressiveness allows us develop a solution. Let's create component that takes array of controls and build the form.

@Component({
  selector: 'app-root',
  template: `<div style="margin: 50px">
 <declarative-form [controls]="controls" (submitMe)="onSubmit($event)"></declarative-form>
</div>`
})
export class AppComponent {

  controls: Object[] = [
    {name: 'name', label: 'Yout name', type: 'text'},
    {name: 'name2nd', label: 'Your second name', type: 'text'},
    new Control('name3rd', 'Your third name'),
    {name : 'description', label: 'Descrition', type: 'textarea' },
    new Control('age', 'Your age', 'range'),
    new Control('mobile', 'Mobile number'),
    new Control('gender', 'Gender', 'radio', {'options' : ['Male', 'Female']}),
    new Control('favFood', 'Favourite Food', 'radio', {'options' : ['Pasta', 'Pizza', 'Hamburgers', 'Soups', 'Chinese']}),
    new Control('country', 'Country', 'dropdown', {'options': ['US','PL', 'DE']}),
  ]

  onSubmit(values) {
    console.log(values);
  }   
}
Ok, let's start with creating declarative-form component
@Component ({
    selector: 'declarative-form',
    template: `<form [formGroup]="form" novalidate>
      <my-form-input *ngFor="let control of controls"
        name="{{control.name}}" 
        label="{{control.label}}" 
        type="{{control.type}}"
        [params]="control.params"
        [form]="form"></my-form-input>
        <button type="submit" (click)="onSubmit()">Submit me</button>
</form>
<pre>{{form.value | json}}</pre>`
})
export class DeclarativeFormComponent{

  @Input()
  controls: Control[];

  @Output()
  submitMe = new EventEmitter();

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit(){
    let cfg = new Object();
    this.controls.forEach(c => cfg[c.name] = '');
    this.form = this.formBuilder.group(cfg);
  }

  onSubmit(){
    console.log(this.form.value);
    this.submitMe.emit(this.form.value);
  }

}
The ngOnInit function is most tricky here. What it does is creating configuration object for the form builder. The last missing piece is my-form-input component - your homework ;)

czwartek, 20 kwietnia 2017

Angular2 - Cannot read property 'id' of undefined for ngModel

Lets take the following piece of code
 <form>
    <select [(ngModel)]="project.id"...
In this case when there is no 'project' value set yet it will be thrown an error with the following message: Cannot read property 'id' of undefined

Maybe '?' operator can help us? Let's try.

 <form>
    <select [(ngModel)]="project?.id"...
Nope, this will cause template parsing error: Parser Error: The '?.' operator cannot be used in the assignment at column 13 in [project?.id=$event]

And what about the ngIf directive?

 <form *ngIf="project" >
    <select [(ngModel)]="project.id"...
Ufff. It works ;)

wtorek, 4 kwietnia 2017

Angular2 - Two ways of injecting dependencies

There are two ways of delivering dependencies to the created object. One is the widely know "injection by type", which is done by specifying typed parameters in constructor.

Inject by Type

constructor(private service: MyService) {
}
This assumes MyService is imported specific class put into providers of your module.

Inject by Name

Another way is "injecting by name".

constructor(@Inject('myService') private service) {
}
This time we required the following in the module providers list
{provide: 'myService', useClass: MyService},
The main advantage of the latter is we actually get rid of importing specific class, though, decouple from other local resources

We can also provide values instead of classes:

{provide: 'url', useValue: 'http://localhost'},

wtorek, 28 marca 2017

Angular2 - How to read params out of the current url

Lets say we want to take `id` param out of the current url. To do so we need to obtain current route by injecting "ActivatedRoute" object and read its params.
    constructor(private _route: ActivatedRoute){
        this.id = _route.params.map(param => param.id);
    }
The `id` field will be of Observable type.

wtorek, 31 stycznia 2017

Spring Security quick dive

To make authentication we need AuthenticationManager instance to call authenticate method on it passing Authentication object. There are couple classes that implement Authentication interface. AbstractAuthenticationToken - an abstract class AnonymousAuthenticationToken UsernamePasswordAuthenticationToken JaasAuthenticationToken RememberMeAuthenticationToken RunAsUserToken TestingAuthenticationToken PreAuthenticatedAuthenticationToken When we'd got authentication token we can validate it against registered AuthenticationProviders (eg. DaoAuthenticationProvider). What is interesting that when we'd got number of providers first one wins (only if returns null as a result authentication is fallbacked to the next provider).

poniedziałek, 30 stycznia 2017

How Spring look for bean definitions?

Scanning for beans

ConfigurationClassBeanDefinitionReader -> loadBeanDefinitionsForConfigurationClass

Constructor Resolver

autowireConstructor(beanName) Method responsible for finding out default parameters. AutoConfigurationPackages @AutoCondifurationPackage annotation user for registering

BeanDefinitionLoader

Four definition reader used. * AnnotationBeanDefintionReader * XmlBeanDefinitionReader * GroovyBeanDefinitionReader * ClassPathBeanDefinitionScanner

Scanning for bean definitions

Where: ClassPathScanningCandidateComponentProvider.java:265 public Set findCandidateComponents(String basePackage) 1. Constructs "search path" (e.g. "classpath*:org.example.services/*.class") 2. Takes all resources matching "search path" 3. If resource is readable it gathers it instantiate MetadataReader which basically is a facade for accessing class metadata such as annotations. 4. Next there is check against Exclude and Include filters. Exclude takes precedence. If class not match against includeFilter it is rejected.

Registering default filters

During creating SpringApplication "Include" filter always contains "Component" annotation type filter. Additionally both "javax.annotation.ManagedBean" (JSR-250) and "javax.inject.Named" (JST-330) are added if appropriate classes found on classpath.

środa, 11 stycznia 2017

Hibernate 5 schema validation internals

SchemaManagementToolCoordinator The static 'process' method takes 'metadata', 'serviceRegistry', 'properties' and 'delayedDropRegistry'. Based on 'properties' values the 'actions' are retrieved. SchemaValidatorImpl doValidation method takes Metadata and ExecutionOptions as a parameters.