Hiển thị các bài đăng có nhãn server management. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn server management. Hiển thị tất cả bài đăng

Enable HTTPS on Wordpress in Amazon

This tutorial will help us install Wordpress on Amazon using a Wordpress image provided by Bitnami. We will also enable HTTPS by using an Amazon's elastic load balancer and a WordPress plugin.

Steps

  1. Create an EC2 instance and install this Wordpress image from Bitnami: https://aws.amazon.com/marketplace/pp/B00NN8Y43U.
  2. Install Easy Https Redirection plugin on Wordpress - https://wordpress.org/plugins/https-redirection/
  3. Configure Elastic Load Balancing With SSL And AWS Certificate Manager For Bitnami Applications On AWS - https://docs.bitnami.com/aws/how-to/configure-elb-ssl-aws/
    These lines should be added before WP_HOME and WP_SITEURL:
    if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
    $_SERVER['HTTPS']='on';
  4. At this stage, your URL should both be accessible via HTTP and HTTPS, but we want to force a redirect to HTTPS so we need to do this final step.
    1. Reopen ~/apps/wordpress/conf/httpd-prefix.conf and add the following lines:
      RewriteCond %{HTTPS} !=on
      RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
      RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  5. And finally, don't forget to restart the apache server: /opt/bitnami/ctlscript.sh restart apache

The final version of the file should look like below. Take note of the commented lines, those are the originals.
SetEnvIf x-forwarded-proto https HTTPS=on

# App url moved to root
DocumentRoot "/opt/bitnami/apps/wordpress/htdocs"
#Alias /wordpress/ "/opt/bitnami/apps/wordpress/htdocs/"
#Alias /wordpress "/opt/bitnami/apps/wordpress/htdocs"

RewriteEngine On
#RewriteCond "%{HTTP_HOST}" ^ec2-([0-9]{1,3})-([0-9]{1,3})-([0-9]{1,3})-([0-9]{1,3})\..*\.amazonaws.com(:[0-9]*)?$
#RewriteRule "^/?(.*)" "%{REQUEST_SCHEME}://%1.%2.%3.%4%5/$1" [L,R=302,NE]

#RewriteCond %{HTTPS} !=on
#RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]

RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Include "/opt/bitnami/apps/wordpress/conf/httpd-app.conf"

Video Tutorial: https://www.youtube.com/watch?v=WQwvwiPZlZE

Setup MySQL Database for Remote Access

Here are some useful guidelines in setting up a mysql server for remote access in Ubuntu.


  1. Install and configure mysql server.
    sudo apt-get update
    sudo apt-get install mysql-server
    mysql_secure_installation
    *Note in MySQL - it will ask to set the password but not in MariaDB
  2. Bind MySQL to the public IP where it is hosted by editing the file MySQL: /etc/conf/my.cnf or MariaDB: /etc/mysql/mariadb.conf.d/50-server.conf, the cnf file is sometimes pointing to another file - make sure to check that. Search for the line with "bind-address" string. Set the value to your IP address or comment the bind-address line.
  3. Make sure that your user has enough privilege to access the database remotely:
    create user 'lacus'@'localhost' identified by 'lacus';
    grant all privileges on *.* to 'lacus'@'localhost' <with grant option>;
    create user 'lacus'@'%' identified by 'lacus';
    grant all privileges on *.* to 'lacus'@'%' <with grant option>;
  4. Open port: 3306 in the firewall:
    sudo ufw allow 3306/tcp
    sudo service ufw restart

How to signin to keycloak using google

There are 3 set of steps that we must follow in order to come up with a web project that will allow us to login using google's identity provider.

Set 1 - Create a google application

  1. Create a google application at https://console.developers.google.com
  2. Set OAuth consent screen
  3. Fill up the requirement to create a client id
  4. Save the client id and secret, we will use it later when creating a client in keycloak

Set 2 - Setup Keycloak

  1.  Create realm social-oauth
  2.  Create Identity Provider
    1.     Identity Provider
    2.     Add provider
    3.     Google
  3. Copy the client id and secret that we save earlier in their respective fields
  4. Create a new keycloak application client
    1. While in the client, click the Installation tab
    2. Under format option select "Keycloak OIDC JSON"
    3. Copy and paste this value in a file named keycloak.json inside your javaee7 web project's web-inf directory.

Set 3 - Create our web project

  1. Create a new maven project using javaee7 blank archetype, name it social-oauth-demo.
  2. Create a file name keycloak.json, content will be coming from the keycloak client that we just created.
    It should look like this:
    {
    "realm": "social-auth",
    "auth-server-url": "http://localhost:8180/auth",
    "ssl-required": "external",
    "resource": "social-auth-client",
    "public-client": true
    }
  3. Create web.xml file, where we will specify keycloak as the authentication method. Also secure a web resource.
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <module-name>social-auth-demo</module-name>

    <security-constraint>
    <web-resource-collection>
    <web-resource-name>All Pages</web-resource-name>
    <url-pattern>/social/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
    <role-name>social-access</role-name>
    </auth-constraint>
    </security-constraint>

    <login-config>
    <auth-method>KEYCLOAK</auth-method>
    <realm-name>social-auth</realm-name>
    </login-config>
    <security-role>
    <role-name>social-access</role-name>
    </security-role>

    </web-app>
  4. Build and deploy the war in wildfly. Make sure that wildfly has keycloak client installed.
  5. Open a browser and enter http://localhost:8080/social-auth-demo/social/index.html, this should redirect to keycloak's login page. You should see a google icon to login.
The same logic applies to facebook.

How to run a wildfly server inside docker

Before we begin you must configure docker, I am using Ubuntu so I followed the guide here: https://docs.docker.com/engine/installation/linux/ubuntulinux/. Choose the appropriate OS that applies to you.

Let's do this in sequence:

  1. Checkout and compile the very basic javaee war from https://github.com/czetsuya/hello-javaee.
  2. In Ubuntu create a new folder: wildfly-hello:
    >mkdir wildfly-hello
  3. Copy hello-javaee.war inside wildfly-hello.
  4. Create a Dockerfile and insert the lines below inside the same folder.

    from jboss/wildfly
    run /opt/jboss/wildfly/bin/add-user.sh admin admin@1234 --silent
    add hello-javaee.war /opt/jboss/wildfly/standalone/deployments/
    cmd ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
  5. Inside the wildfly-hello folder build the Dockerfile.
    >docker build -it wildfly-hello .
  6. Run the docker image
    >docker run wildfly-hello
  7. Get the ip address of the container by:
    >docker ps - to get the container id
    >docker inspect -f '{{ .NetworkSettings.IPAddress }}' CONTAINER_ID
  8. Now we should have the ip address of docker, we can now open wildfly in the browser.
What does the lines in step 3 means?
-from is a docker keyword use to import an image from docker hub hub.docker.com
-run is a command that runs an executable file, in this case we are adding a user with application management role
-add lets us add a file inside the container
-cmd tells the docker to execute this by default, when we execute docker run

How to handle an xmlrcp wordpress attack on nginx server

I'm not really a system administrator and these steps are just based on my personal experience in securing our own wordpress websites.

Lately there has been a lot of attacks on wordpress sites (since it's a popular framework) specially on windows machine. So we decided to migrate on a linux machine. Obviously got a lot of attacks still, one of the nasty one is a DoS (denial of service), and here's how we handled it:


  1. Install akismet plugin.
  2. Install wordfence plugin - this one is really good.
  3. If you know how to type commands on linux, run tail -f /var/log/nginx/access.log. This will should the most frequent request together with its IP take note of it and under WordFence->Blocked IPs, add it.
  4. Install and configure ip tables. 
  5. Block the ip in ip tables (INPUT section):
    //add
    sudo iptables -A INPUT -s [IP ADDRESS] -j DROP

    //or insert as a first rule
    sudo iptables -I INPUT 1 -s [IP ADDRESS] -j DROP

    //check if configured correctly
    sudo iptables -L --line-numbers

    //to remove a rule
    iptables -D INPUT [line-number]
  6. Configure nginx.conf to block xmlrpc request (make sure that you are not using it). Normally you don't. Create nginx.conf in your webroot with the following contents:
    # nginx configuration
    location /xmlrpc.php {
    deny all;
    }
    Here's an htaccess to nginx converter, just in case you need: http://winginx.com/en/htaccess.
  7. Setup fail2ban. Google on how-to. Here's my favorite: https://www.digitalocean.com/community/tutorials/how-to-protect-an-nginx-server-with-fail2ban-on-ubuntu-14-04.

How to setup a subdomain in your nginx server

Lately I've created a sub-domain for one of my website. I hope you follow this blog on how to setup your nginx wordpress site. In the same server where I host my maindomain.com, I've added a subdomain.maindomain.com. And here is how:

  1. I created a new folder in /var/www/subdomain where I install a new copy of wordpress. Note that /var/www/html contains my maindomain.
  2. The duplicate the config site in the blog I mentioned above (my-site), so now I have subdomain ni /etc/nginx/sites-available.
  3. Make the following modifications (first 2 lines):
    listen 80;
    listen [::]:80;
  4. Basically, you can't have 2 virtual configurations with default_server marker.
  5. Your sub domain should now be accessible.

How to setup your wordpress website in nginx server

Long ago I learned of the advantages of nginx over apache, just google it. Planned to migrate our sites but didn't manage to do it until last weekend. So here's what I did to do that:

I'm assuming you already have a functional wordpress with mysql setup and html / php files in /var/www/html (the usual).

First we need to install nginx and php:

sudo apt-get install nginx php5-fpm

Next, configure nginx virtual config, like in apache. Default config file is at /etc/nginx/sites-available/default, copy it and edit like below:

//copy
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/my-site

//modify my-site
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;

root /var/www/html;
index index.php index.html index.htm;

server_name your_domain.com;

location / {
# try_files $uri $uri/ =404;
try_files $uri $uri/ /index.php?q=$uri&$args;
}

error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}

//remove default enabled site
rm /etc/nginx/sites-enabled/default

//enable my-site
ln -s /etc/nginx/sites-available/my-site /etc/nginx/sites-enabled/

//restart or reload
sudo service nginx restart
sudo service php5-fpm restart

Your website should now be up and running in nginx.

*Keep your eye on missing comma ;.

How to run automate undeploy, redeployment in jboss using jenkins

Deploy on the same server where jenkins is deployed.
JBOSS_HOME/bin/jboss-cli.sh -c --user="czetsuya" --password="broodcamp.com" --commands="undeploy broodcamp.war,deploy $WORKSPACE/broodcamp/target/broodcamp.war"

Deploy on a different server.
JBOSS_HOME/bin/jboss-cli.sh controller=127.0.0.3 -c --user="czetsuya" --password="broodcamp.com" --commands="undeploy broodcamp.war,deploy $WORKSPACE/broodcamp/target/broodcamp.war"

REST Testing with Arquillian in JBoss

This article will explain how we can automate REST web service testing using Arquillian and JBoss web server.

First, you must create a javaee6 war (non-blank) project from jboss-javaee6 archetype. This should create a project with Member model, service, repository, controller and web service resource. The archetype will also generate a test case for the controller with test data source and persistence file.

In case you don't have the archetype, I'm writing the most important classes: Model
package com.broodcamp.jboss_javaee6_war.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

@SuppressWarnings("serial")
@Entity
@XmlRootElement
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class Member implements Serializable {

@Id
@GeneratedValue
private Long id;

@NotNull
@Size(min = 1, max = 25)
@Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
private String name;

@NotNull
@NotEmpty
@Email
private String email;

@NotNull
@Size(min = 10, max = 12)
@Digits(fraction = 0, integer = 12)
@Column(name = "phone_number")
private String phoneNumber;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPhoneNumber() {
return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
Web service resource:
package com.broodcamp.jboss_javaee6_war.rest;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.NoResultException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.broodcamp.jboss_javaee6_war.data.MemberRepository;
import com.broodcamp.jboss_javaee6_war.model.Member;
import com.broodcamp.jboss_javaee6_war.service.MemberRegistration;

/**
* JAX-RS Example
* <p/>
* This class produces a RESTful service to read/write the contents of the
* members table.
*/
@RequestScoped
public class MemberResourceRESTService implements IMemberResourceRESTService {

@Inject
private Logger log;

@Inject
private Validator validator;

@Inject
private MemberRepository repository;

@Inject
MemberRegistration registration;

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Member> listAllMembers() {
return repository.findAllOrderedByName();
}

@GET
@Path("/{id:[0-9][0-9]*}")
@Produces(MediaType.APPLICATION_JSON)
public Member lookupMemberById(@PathParam("id") long id) {
Member member = repository.findById(id);
if (member == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return member;
}

/**
* Creates a new member from the values provided. Performs validation, and
* will return a JAX-RS response with either 200 ok, or with a map of
* fields, and related errors.
*/
@Override
public Response createMember(Member member) {

Response.ResponseBuilder builder = null;

try {
// Validates member using bean validation
validateMember(member);

registration.register(member);

// Create an "ok" response
builder = Response.ok();
} catch (ConstraintViolationException ce) {
// Handle bean validation issues
builder = createViolationResponse(ce.getConstraintViolations());
} catch (ValidationException e) {
// Handle the unique constrain violation
Map<String, String> responseObj = new HashMap<String, String>();
responseObj.put("email", "Email taken");
builder = Response.status(Response.Status.CONFLICT).entity(
responseObj);
} catch (Exception e) {
// Handle generic exceptions
Map<String, String> responseObj = new HashMap<String, String>();
responseObj.put("error", e.getMessage());
builder = Response.status(Response.Status.BAD_REQUEST).entity(
responseObj);
}

return builder.build();
}

/**
* <p>
* Validates the given Member variable and throws validation exceptions
* based on the type of error. If the error is standard bean validation
* errors then it will throw a ConstraintValidationException with the set of
* the constraints violated.
* </p>
* <p>
* If the error is caused because an existing member with the same email is
* registered it throws a regular validation exception so that it can be
* interpreted separately.
* </p>
*
* @param member
* Member to be validated
* @throws ConstraintViolationException
* If Bean Validation errors exist
* @throws ValidationException
* If member with the same email already exists
*/
private void validateMember(Member member)
throws ConstraintViolationException, ValidationException {
// Create a bean validator and check for issues.
Set<ConstraintViolation<Member>> violations = validator
.validate(member);

if (!violations.isEmpty()) {
throw new ConstraintViolationException(
new HashSet<ConstraintViolation<?>>(violations));
}

// Check the uniqueness of the email address
if (emailAlreadyExists(member.getEmail())) {
throw new ValidationException("Unique Email Violation");
}
}

/**
* Creates a JAX-RS "Bad Request" response including a map of all violation
* fields, and their message. This can then be used by clients to show
* violations.
*
* @param violations
* A set of violations that needs to be reported
* @return JAX-RS response containing all violations
*/
private Response.ResponseBuilder createViolationResponse(
Set<ConstraintViolation<?>> violations) {
log.fine("Validation completed. violations found: " + violations.size());

Map<String, String> responseObj = new HashMap<String, String>();

for (ConstraintViolation<?> violation : violations) {
responseObj.put(violation.getPropertyPath().toString(),
violation.getMessage());
}

return Response.status(Response.Status.BAD_REQUEST).entity(responseObj);
}

/**
* Checks if a member with the same email address is already registered.
* This is the only way to easily capture the
* "@UniqueConstraint(columnNames = "email")" constraint from the Member
* class.
*
* @param email
* The email to check
* @return True if the email already exists, and false otherwise
*/
public boolean emailAlreadyExists(String email) {
Member member = null;
try {
member = repository.findByEmail(email);
} catch (NoResultException e) {
// ignore
}
return member != null;
}
}
Member resource interface to be use in arquillian testing:
package com.broodcamp.jboss_javaee6_war.rest;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.broodcamp.jboss_javaee6_war.model.Member;

@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
@Path("/members")
public interface IMemberResourceRESTService {

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/")
public Response createMember(Member member);

}

And finally the test class that creates the archive and deploy it on jboss container:
package com.broodcamp.jboss_javaee6_war.test;

import java.net.URL;

import javax.inject.Inject;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.apache.http.HttpStatus;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.extension.rest.client.ArquillianResteasyResource;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broodcamp.jboss_javaee6_war.model.Member;
import com.broodcamp.jboss_javaee6_war.rest.IMemberResourceRESTService;
import com.broodcamp.jboss_javaee6_war.rest.JaxRsActivator;
import com.broodcamp.jboss_javaee6_war.service.MemberRegistration;

@RunWith(Arquillian.class)
public class MemberResourceRESTServiceTest {

private Logger log = LoggerFactory
.getLogger(MemberResourceRESTServiceTest.class);

@ArquillianResource
private URL deploymentURL;

@Deployment(testable = false)
public static Archive createTestArchive() {
return ShrinkWrap
.create(WebArchive.class, "rest.war")
.addClass(JaxRsActivator.class)
.addPackages(true, "com/broodcamp/jboss_javaee6_war")
.addAsResource("META-INF/test-persistence.xml",
"META-INF/persistence.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
// Deploy our test datasource
.addAsWebInfResource("test-ds.xml");
}

@Inject
MemberRegistration memberRegistration;

@Test
public void testCreateMember(
@ArquillianResteasyResource IMemberResourceRESTService memberResourceRESTService)
throws Exception {
Member newMember = new Member();
newMember.setName("czetsuya");
newMember.setEmail("czetsuya@gmail.com");
newMember.setPhoneNumber("1234567890");

Response response = memberResourceRESTService.createMember(newMember);

log.info("Response=" + response.getStatus());

Assert.assertEquals(response.getStatus(), HttpStatus.SC_OK);
}

}

To run that we need the following dependencies:
For arquillian testing:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
For rest testing:
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-3x</artifactId>
<version>1.0.0.Alpha3</version>
</dependency>

<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>${version.resteasy}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-jersey</artifactId>
<version>1.0.0.Alpha3</version>
<scope>test</scope>
</dependency>

To run the test we need to create a maven profile as follows:
<profile>
<!-- Run with: mvn clean test -Parq-jbossas-managed -->
<id>arq-jbossas-managed</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>

arquillian.xml to be save inside the src/test/resources folder.

<?xml version="1.0" encoding="UTF-8"?>
<!-- JBoss, Home of Professional Open Source Copyright 2013, Red Hat, Inc.
and/or its affiliates, and individual contributors by the @authors tag. See
the copyright.txt in the distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

<!-- Uncomment to have test archives exported to the file system for inspection -->
<!-- <engine> -->
<!-- <property name="deploymentExportPath">target/</property> -->
<!-- </engine> -->

<!-- Force the use of the Servlet 3.0 protocol with all containers, as it
is the most mature -->
<defaultProtocol type="Servlet 3.0" />

<!-- Example configuration for a remote WildFly instance -->
<container qualifier="jboss" default="true">
<!-- By default, arquillian will use the JBOSS_HOME environment variable.
Alternatively, the configuration below can be uncommented. -->
<configuration>
<property name="jbossHome">C:\java\jboss\jboss-eap-6.2</property>
<!-- <property name="javaVmArguments">-Xmx512m -XX:MaxPermSize=128m -->
<!-- -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y -->
<!-- </property> -->
</configuration>
</container>

<engine>
<property name="deploymentExportPath">target/deployments</property>
</engine>

</arquillian>
And invoke maven as: mvn clean test -Parq-jbossas-managed

How to initialize a git repository and linked it to a remote repository provider

For example we've just created a new project and want to push it to a remote repository. Here's what we need to do.

  1. Find out what is the repository url, you can see it at github. For example: https://github.com/czetsuya/JAX-RS-REST-Security.git
  2. Open command prompt
  3. Change directory to where your project is.
  4. In the command promp execute:
    1. >git init
    2. >git add .
    3. >git commit -m "Initial commit"
    4. >git remote add origin https://github.com/czetsuya/JAX-RS-REST-Security.git
    5. >git push -u origin master
What if we already initialized our repository? Then we can already skip steps 4.1-4.3 and just execute:
  1. >git remote add origin https://github.com/czetsuya/JAX-RS-REST-Security.git
  2. >git push -u origin master

How to configure Wildfly 8 clustering and deploying picketlink enabled war application to test the session.

In this tutorial we will try to configure wildfly cluster and test it by deploying a picketlink enabled war application where a user can login and the session shared between the virtual server.

Before we start, make sure that you read these links:
https://docs.jboss.org/author/display/AS71/AS7+Cluster+Howto
http://blog.arungupta.me/2014/03/wildfly-8-clustering-and-session-failover/

The concept of wildfly clustering is already discussed in the previous links so we will just enumerate the steps we've done and provide a sample war.

This is how I configured my servers (note that I'm using Wildfly 8.1 Final). Basically we have 2 physical machine, windows (master) and slave (ubuntu). Windows is the domain controller, while ubuntu has host controller and 2 virtual servers. Note that we need to manually deploy wildfly on both servers.

-Windows (IP=192.168.0.100)
--domain controller
-Ubuntu (IP=192.168.0.116)
--host controller

2 server groups
-main-server-group
-other-server-group

You may refer to the following images for reference.
Master
Slave

We need to create a slave user in the master's machine. This user will be use by the slave server later on. To create a user account (username / password) run wildfly/bin/add-user.bat. Take note of the password as we will need to convert it later to base64.

Here are the configuration changes that we need to do:
On master, wildfly/domain/configuration/host.xml, we need to update the correct ip address, don't use 127.0.0.1:
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:192.168.0.100}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:192.168.0.100}"/>
</interface>
<interface name="unsecure">
<inet-address value="${jboss.bind.address.unsecure:192.168.0.100}"/>
</interface>
</interfaces>

Then on slave machine, rename host.xml to host.bak.xml and rename host-slave.xml to host.xml. We need to update the following:
//set host name to slave
<host name="slave" xmlns="urn:jboss:domain:2.1">

//set domain controller, point to master's ip
<domain-controller>
<remote host="192.168.0.100" port="${jboss.domain.master.port:9999}" security-realm="ManagementRealm"/>
</domain-controller>

//set the secret key, basically it's the base64 representation of your slave password
//http://www.freeformatter.com/base64-encoder.html
<server-identities>
<!-- Replace this with either a base64 password of your own, or use a vault with a vault expression -->
<secret value="xxxxxx"/>
</server-identities>

In your master's domain.xml file, don't forget to set the hornetq-server's cluster-password.
<subsystem xmlns="urn:jboss:domain:messaging:2.0">
<hornetq-server>
<cluster-password>${jboss.messaging.cluster.password:absolutely}</cluster-password>

Run the server on both machine. And you should get the images I've posted above. The topology will become:



To test if the clustering is working download the project from:
https://github.com/czetsuya/picketlink-authentication-jsf

Download, build with maven and deploy on the 2 server groups:

Now we can access the application from:
http://192.168.0.110:8080/jboss-as-picketlink-authentication-jsf/home.jsf

To test if clustering is working we need to setup cluster module from apache which is properly documented here: https://docs.jboss.org/author/display/AS71/AS7+Cluster+Howto.

Custom application context or name in Jboss or Wildfly

As far as I know there are 3 ways to deploy an application in JBoss or Wildfly with a custom application context name.

1.) By adding jboss-web.xml in your web project WEB-INF folder;
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>/</context-root>
</jboss-web>

2.) Adding application.xml in your ear's META-INF folder:
<?xml version="1.0" encoding="UTF-8"?>
<application version="5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/application_5.xsd">
<module>
<ejb>czetsuya-ejb.jar</ejb>
</module>
<module>
<web>
<web-uri>czetsuya.war</web-uri>
<context-root>/</context-root>
</web>
</module>
</application>

3.) In your ear's pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${version.ear.plugin}</version>
<configuration>
<!-- Tell Maven we are using Java EE 6 -->
<version>6</version>
<!-- Use Java EE ear libraries as needed. Java EE ear libraries are
in easy way to package any libraries needed in the ear, and automatically
have any modules (EJB-JARs and WARs) use them -->
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>

<webModule>
<groupId>com.kbs</groupId>
<artifactId>czetsuya-web</artifactId>
<contextRoot>/</contextRoot>
</webModule>

</modules>
<fileNameMapping>no-version</fileNameMapping>
</configuration>
</plugin>

How to change the context url in jboss or wildfly

Normally when we create a new war or ear, for example demo-project.war or demo-project.war inside demo-project.ear. The context root or url to which we can access the web application is:

http://localhost:8080/demo-project

But what if we want to change context root or in this case demo-project to let's say "demo" only.

Steps:
1.) In the web project create a new file: src/main/webapp/WEB-INF/jboss-web.xml

2.) Enter the following content
<jboss-web>
<context-root>demo</context-root>
</jboss-web>

GIT: How to have 2 local branch pushing to 2 different remote repositories so that you can merge code

This tutorial will explain how to create 2 local branches with the same code base, each linked to different repository. The purpose is that you can share code between repositories. For example in a multi-module project, it's possible that 1 project will have different implementation depending on the client.

Assumptions:
1.) You have a github account.
2.) You already have 1 project pushed in your account.
3.) You have another empty github project.

Steps:
1.) Add the empty remote repository, name it clone.
2.) Create a local branch name clone -> select checkout new branch.
3.) Push to upstream so that the local branch will be added to the original repository.
4.) Configure clone branch set remote=clone.
5.) Double click clone local branch.
6.) Push to upstream to commit the changes to the empty repository. Go to github and check if the project is properly pushed.
7.) You can now switch between local branch and push to the necessary remote branch.
*Note: The 2 local branch can now be merge

What if you want to delete the remote repository and the clone branch in your original project?
1.) Delete local clone branch, first you mush double click the master branch so the clone branch is not active.
2.) In command prompt go to the first repository's directory and execute: git push origin --delete clone
3.) Delete remote branch

JBoss datasource configuration settings

The following are sample configurations for different database (it's in the file standalone.xml subsystem=datasources):
H2, postgresql, mysql
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<datasource jta="false" jndi-name="java:jboss/datasources/PostgreDatasource" pool-name="PostgrePool" enabled="true" use-java-context="true" use-ccm="false">
<connection-url>jdbc:postgresql://localhost:5432/postgre</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgresql</driver>
<pool>
<min-pool-size>2</min-pool-size>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>postgre</user-name>
<password>postgre</password>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
<background-validation-millis>1</background-validation-millis>
</validation>
<statement>
<prepared-statement-cache-size>10</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
<datasource jta="false" jndi-name="java:jboss/datasources/mysqlDataSource" pool-name="mysqlPool" enabled="true" use-java-context="true" use-ccm="false">
<connection-url>jdbc:mysql://localhost:3306/mysql</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver>com.mysql</driver>
<pool>
<min-pool-size>2</min-pool-size>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>mysql</user-name>
<password>mysql</password>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
<background-validation-millis>1</background-validation-millis>
</validation>
<statement>
<prepared-statement-cache-size>10</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
<datasource jndi-name="java:jboss/datasources/VmlaDS" pool-name="vmlaDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://localhost:3306/vlma</connection-url>
<driver>mysql</driver>
<security>
<user-name>vlma</user-name>
<password>vlma</password>
</security>
<statement>
<prepared-statement-cache-size>100</prepared-statement-cache-size>
<share-prepared-statements>true</share-prepared-statements>
</statement>
</datasource>
<drivers>
<driver name="mysql" module="com.sql.mysql">
<driver-class>com.mysql.jdbc.Driver</driver-class>
</driver>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="postgresql" module="org.postgresql">
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
</driver>
<driver name="com.mysql" module="com.mysql">
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
<datasource jndi-name="java:jboss/datasources/germ-popperDS" pool-name="GermPopperPool" enabled="true" use-java-context="true">
<connection-url>jdbc:jtds:sqlserver://localhost:1433/germpopper;loginTimeout=30;instance=sqlexpress</connection-url>
<driver>JTDS</driver>
<new-connection-sql>select 1</new-connection-sql>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>50</max-pool-size>
</pool>
<security>
<user-name>unicomi</user-name>
<password>unicomi</password>
</security>
<validation>
<check-valid-connection-sql>select 1</check-valid-connection-sql>
</validation>
<timeout>
<set-tx-query-timeout>true</set-tx-query-timeout>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
</timeout>
<statement>
<track-statements>false</track-statements>
</statement>
</datasource>

Then add the following modules in: jboss-as-7.1.3.Final\modules
  1. postgresql
    1. create org/postgresql/main
    2. download and paste: postgresql-9.2-1002.jdbc4.jar
    3. create module.xml with these contents
    4. <?xml version="1.0" encoding="UTF-8"?>
      <module xmlns="urn:jboss:module:1.0" name="org.postgresql">
      <resources>
      <resource-root path="postgresql-9.2-1002.jdbc4.jar"/>
      </resources>
      <dependencies>
      <module name="javax.api"/>
      <module name="javax.transaction.api"/>
      </dependencies>
      </module>
  2. mysql
    1. create com/mysql/main
    2. download mysql-connector-java
    3. create module.xml with these contents
    4. <?xml version="1.0" encoding="UTF-8"?>  
      <module xmlns="urn:jboss:module:1.0" name="com.mysql">
      <resources>
      <resource-root path="mysql-connector-java-5.1.21.jar"/>
      </resources>
      <dependencies>
      <module name="javax.api"/>
      </dependencies>
      </module>
  3. MSSQL

  4. <driver name="JTDS" module="net.sourceforge.jtds">
    <driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class>
    <xa-datasource-class>net.sourceforge.jtds.jdbcx.JtdsDataSource</xa-datasource-class>
    </driver>