Varnish Cache für Webserver

Varnish Installieren

$ sudo apt-get install varnish

Varnish Konfigurieren

Die Standardkonfigurationen von Varnish findet ihr unter /etc/default/varnish und /etc/varnish/default.vcl

Für den Cache wird in der /etc/default/varnish ein daemon konfiguriert der nach der Installation per sudo bereits vorkonfiguriert ist. Ihr könnt zur Sicherheit noch einmal nachsehen.

DAEMON_OPTS="-a :6081  
             -T localhost:6082  
             -f /etc/varnish/default.vcl  
             -S /etc/varnish/secret  
             -s malloc,256m"

Der Port des daemon wird nach der Konfiguration von 6081 auf 80 geändert.

In der /etc/varnish/default.vcl wird der listener definiert auf den varnish hört.

backend default {
    .host = "127.0.0.1"; 
    .port = "80"; 
}

Für eine detailierte Information und ein paar Erklärunge könnt ihr gerne unter: Sitepoint – Getting Started with Varschnish nachsehen und auch diese Verweise weiterarbeiten.

Primefaces 5 SelectOneMenu + Hibernate + Wildfly and Entities

Die letzten zwei Tage waren wieder eine Suche nach dem richtigen Weg. Im Normalfall würde sich mein JPA Manager um eine performante Art und Weise kümmern meine Daten zwischen zu lagern oder neu zu laden. Hibernate geht leider eine etwas andere Logik vor und cached nicht lange genug die Entities vor. Das heißt bei einem Neuaufruf über eine andere Bean wird nicht vom Application Server geladene Inhalte übertragen sondern die Abfrage erneut gestartet. Somit wäre ein flushen im Entity Manager nach dem updaten von Inhalten nur optional.

Es ist ziemlich einfach wenn man weiß woran es liegt. Und zwar wird bei Entities eine equals Methode geladen z.b.

package de.kuw.jee.core.verwaltung;

import java.io.Serializable;

import javax.persistence.*;

import java.util.List;
import java.util.logging.Logger;


/**
 * The persistent class for the virtual_domains database table.
 * 
 */
@Entity
@Table(name="virtual_domains")
@NamedQuery(name="VirtualDomain.findAll", query="SELECT v FROM VirtualDomain v")
public class VirtualDomain implements Serializable {
	private static final long serialVersionUID = 1L;
	private static final Logger log = Logger.getLogger(VirtualDomain.class.getName());

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;

	private boolean active;

	private boolean deleted;

	private String directory;

	@Column(name="domain_type")
	private String domainType;

	private String name;

	//bi-directional many-to-one association to SysDomain
	@OneToMany(mappedBy="virtualDomain")
	private List sysDomains;

	//bi-directional many-to-one association to VirtualAlias
	@OneToMany(mappedBy="virtualDomain")
	private List virtualAliases;

	//bi-directional many-to-one association to BillCustomer
	@ManyToOne
	@JoinColumn(name="customer_id")
	private BillCustomer billCustomer;

	//bi-directional many-to-one association to VirtualUser
	@OneToMany(mappedBy="virtualDomain")
	private List virtualUsers;

	public VirtualDomain() {
	}

	public int getId() {
		return this.id;
	}

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

	public boolean getActive() {
		return this.active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public boolean getDeleted() {
		return this.deleted;
	}

	public void setDeleted(boolean deleted) {
		this.deleted = deleted;
	}

	public String getDirectory() {
		return this.directory;
	}

	public void setDirectory(String directory) {
		this.directory = directory;
	}

	public String getDomainType() {
		return this.domainType;
	}

	public void setDomainType(String domainType) {
		this.domainType = domainType;
	}

	public String getName() {
		return this.name;
	}

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

	public List getSysDomains() {
		return this.sysDomains;
	}

	public void setSysDomains(List sysDomains) {
		this.sysDomains = sysDomains;
	}

	public SysDomain addSysDomain(SysDomain sysDomain) {
		getSysDomains().add(sysDomain);
		sysDomain.setVirtualDomain(this);

		return sysDomain;
	}

	public SysDomain removeSysDomain(SysDomain sysDomain) {
		getSysDomains().remove(sysDomain);
		sysDomain.setVirtualDomain(null);

		return sysDomain;
	}

	public List getVirtualAliases() {
		return this.virtualAliases;
	}

	public void setVirtualAliases(List virtualAliases) {
		this.virtualAliases = virtualAliases;
	}

	public VirtualAlias addVirtualAlias(VirtualAlias virtualAlias) {
		getVirtualAliases().add(virtualAlias);
		virtualAlias.setVirtualDomain(this);

		return virtualAlias;
	}

	public VirtualAlias removeVirtualAlias(VirtualAlias virtualAlias) {
		getVirtualAliases().remove(virtualAlias);
		virtualAlias.setVirtualDomain(null);

		return virtualAlias;
	}

	public BillCustomer getBillCustomer() {
		return this.billCustomer;
	}

	public void setBillCustomer(BillCustomer billCustomer) {
		this.billCustomer = billCustomer;
	}

	public List getVirtualUsers() {
		return this.virtualUsers;
	}

	public void setVirtualUsers(List virtualUsers) {
		this.virtualUsers = virtualUsers;
	}

	public VirtualUser addVirtualUser(VirtualUser virtualUser) {
		getVirtualUsers().add(virtualUser);
		virtualUser.setVirtualDomain(this);

		return virtualUser;
	}

	public VirtualUser removeVirtualUser(VirtualUser virtualUser) {
		getVirtualUsers().remove(virtualUser);
		virtualUser.setVirtualDomain(null);

		return virtualUser;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj != null) {
			log.info("Equals action in VirtualDomain for obj: " 
					 + obj.toString());
		}
		return super.equals(obj);
	}
}

Zum testen habe ich die equals Methode rausgezogen um zu sehen was geprüft wird im selectOneMenu von Primefaces. Und wie ich es mir gedacht habe. Wildfly weiß nicht mehr das die Daten in der view schon existieren und werden daher nochmal aus der DB geladen und somit natürlich einen anderen Hash zugeordnet. Um diesen Fehler des: „value not valid“ zu vermeiden müsst ihr die Bean die ViewScoped per CDI Injected wird die Wertetabelle rausziehen z.B.


Der Primefaces

package de.kuw.jee.verwaltung.converter;

import java.util.logging.Logger;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

import de.kuw.jee.core.verwaltung.VirtualDomain;
import de.kuw.jee.verwaltung.mb.DomainBean;

@FacesConverter("domainConverter")
public class DomainConverter implements Converter {
	private Logger log = Logger.getLogger(DomainConverter.class.getName());
	
	@Inject
	private DomainBean domainBean;
	
	private int id;
	
	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String value) {
		VirtualDomain dom = null;
        id = Integer.valueOf(value);
        if(value != null && id > 0) {
        	for(VirtualDomain tmp : domainBean.getDomains()) {
        		if(tmp.getId() == id) {
        			dom = tmp;
        		}
        	}
        	
        	log.info("Object is: " + dom.toString() );
        }
        
        return dom;
    }

	@Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    	String returnVal = "";
    	if(value instanceof VirtualDomain) {
    		 VirtualDomain dom = (VirtualDomain) value;
    		 returnVal = String.valueOf(dom.getId());
    	} else {
    		returnVal = "";
    	}
    	log.finest("GetAsString is: " + returnVal);
        return returnVal;
    }
}

Sobald ihr das beachtet, und aus bestehenden Datasets lest, werdet ihr den Fehler der falschen Hashed und equals Fehler nicht mehr bekommen.

viel Spaß beim ausprobieren.

Citrix ICA Client / Receiver für Ubuntu

Für alle die ein Linux bzw. ein Ubuntu verwenden und den Citrix Receiver in der Version 13 installieren wollen. Ihr könnt diese Installationsanleitung:

https://help.ubuntu.com/community/CitrixICAClientHowTo

für alle nötigen Ubuntu Versionen benützen. Ebenso funktioniert die Anleitiung:

Citrix Receiver 13.0 on Ubuntu 13.10 64-bit

auch für Ubuntu 14.04 ohne Probleme. Wer aber nach dem Start Probleme hat das das Tastaturlayout nicht erkannt wird muss folgenden Eintrag ändern:

vim /opt/Citrix/ICAClient/config/wfclient.ini

anschließend den Parameter

KeyboardLayout = (User Profile)

ändern in z.B.

KeyboardLayout = GERMAN

Es wird zwar weiterhin ein Fehler angezeigt vor allem das die GTK nicht aufgerufen werden kann aber der Client kann zumindest mit einem vernünftigen Layout gestartet werden.

Magento mit aktueller PHP Version 5.4.+

Magento hat Probleme mit der aktuellen PHP Version um PDF’s für Rechnungen erzeugen zu können. Um diesen Fehler zu beheben muss im Zend Framework eine File angepasst werden.

Resultat: Funktioniert! 🙂

Auszug aus StackOverflow

This an incompatibility issue between PHP Version 5.4.4 and zend Framwork .

Fixed it by change in this function lib/Zend/Pdf/FileParserDataSource.php.

change

abstractpublicfunction __construct();

to

abstractpublicfunction __construct($filePath);

Crossfit Games 2014

Bald ist es so weit. Crossfit Games 2014 starten in die nächste Runde. Nachdem 2013 schon überaus beeindruckend war gibt es noch ein paar Impressionen aus dem letzen Jahr.

In ein paar Tagen geht es die die nächste Runde. Games 2014, ich werde mir auf jeden Fall den Livestream reinziehen. Hier der Channel von Crossfit.

Weitere Informationen zu den Games, Athleten und co findet ihr auch unter games.crossfit.com

Crossfit – Schienbein offen

So ein Scheiß. Normalerweise beginnt man damit keine Sätze aber dieses mal trifft es voll zu. Enthusiasmus muss sein, Begeisterung bei Sport und körperlicher Ertüchtigung. Ich liebe es mich zu bewegen. Laufen, Springen, Gewichtheben oder seit knapp 8 Monaten Crossfit in „The Box“- Kulmbach.

Ralf Müller unser Crossfit Coach ist klasse, und die Mitstreiter die jeden Tag aufs neue Ihre Grenzen kennen lernen wollen. Einfach eine Klasse Mannschaft. Nächste Jahr greifen wir so richtig an. Egal ob CMAR, Crossfit Games oder andere Events die uns eine Herausforderung bietet.

Zurück zum eigentlichen Thema. Wie blöd darf/kann man sein. Boxjumps, so einfach wie es sich anhört sollte man meinen kann’s doch nicht anders sein. Hoch- Runter- von der Box, immer wieder und wieder. Aber irgendwann verlässt einem die Konzentration, innerhalb von Bruchteilen einer Sekunde rutscht man ab. Und dann?! … Offen… das Schienbein. Kurz fluchen, Schweiß aus dem Gesicht wischen und weiter gehts. Die letzen Reps werden durchgezogen. Danach ist Zeit nach dem Bein zu sehen.

Entkräftet und Fertig am Boden liegend begutachtet man sein Bein und stellt, mal wieder fest … offen. Selbe Stelle wie vor ein paar Wochen. Da gings aber gut aus. Nach 2- 3 Tagen war ein Grint gewachsen und man konnte sich wieder dem Crossfit und seinem eigenen Schweinehund widmen. Aber dieses mal war es anders. Mein offenes Bein, immer noch am siffen. Nach knapp 2 Wochen. Ich könnte verrückt werden. Letzte Woche Antibiotika, diese Woche Antibiotika. Gesund kann das auch nicht sein aber man versucht alles um schnell wieder fit zu werden. Entgegen dem eigenen Drang sich bewegen zu wollen sitzt man Stunden auf der Couch ab. Manche sind ganz froh darüber den Couchpotatoe zu mimen aber mich nervt’s nur.

Morgen geht’s wieder zur Ärztin. Mal sehen was dieses mal dabei raus kommt. Bisher hat weder der Chirurg noch die Hausärztin eine wirkliche Diagnose gestellt, die ich verstehen würde. 😉 Kopf hoch und keep on… Auf das die Tragödie bald rum ist. Ich freue mich wieder auf die Truppe.

Kleines Update, nichts für schwache nerven.
image

Android – HowTo Intent Service

Was ist ein IntentService?

Ein Intent Service ist eine abgekapselte Art des Services. Viel kleiner und schlankter als der ServiceLayer und somit einfacher zu bedienen.

Wozu benötige ich einen IntentService?

Der IntentService wird benötigt um z.B. einfache Downloads bzw. Uploads zu starten. Wenn nur eine Aktion ausgeführt werden soll ohne die Activity zu verlassen. z.B. Downloaden von Bibiliotheken, Bilder oder ähnlichen Aktionen ohne die Applikation dabei zu verlassen. Der Service wird beendet sobald onPause oder onStop ausgeführt wird.

Wie setzte ich einen IntentService ein / HowTo Setup an IntentService?

Prepare ActivityView

Um einen IntentService aufrufen zu können benötigt man relativ wenig Vorbereitung. Da der Service nur gebunden zu einer Activity aufgerufen werden kann wird er ähnlich einer Activity gestartet.

Es können dem Service per Extra werte übergeben werden die anschließend ausgelesen werden.

Intent intent = new Intent(this, IntentTestService.class);
intent.putExtra(IntentTestService.EXTRA_TEST,"test");
startService(intent);

 

Prepare IntentService

 

package de.good.study.app.android.service;

import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

/**
 * Created by jkoeber on 06.03.14.
 */
public class IntentTestService extends IntentService {
    private static final String CLASS_NAME = IntentTestService .class.getName();
    public static final String CUSTOM_INTENT = IntentTestService .class.getName()+".Receiver";
    public static final String RESULT = "serviceResult";
    public static final String STATUS = "serviceStatus";
    public static final int STATE_FINAL = 20;

    public DatabaseService() {
        super("IntentTestService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        int i = 0;

        Log.i(CLASS_NAME,"==> Service Started!");
        long endTime = 2*1000;
        while (i < STATE_FINAL) {
            synchronized (this) {
                try {
                    i += 1;
                    publishStatus(i);
                    wait(endTime);
                } catch (Exception e) {
                    Log.e(this.getClass().getName(),"Error by executing the service");
                }
            }
        }
    }

    /**
     * publish status
     * @param status
     */
    private void publishStatus(int status) {
        Intent intent = new Intent(CUSTOM_INTENT);
        intent.putExtra(STATUS, status);

        if(status == STATE_FINAL) {
            intent.putExtra(RESULT, Activity.RESULT_OK);
        } else {
            intent.putExtra(RESULT, Activity.RESULT_CANCELED);
        }

        sendBroadcast(intent);
    }
}

 

Response konsumieren

 

Die Activity kann anschließend den Response vom Service verarbeiten und abfangen über einen BroadcastListener. Hier ein Beispiel

    /**
     * BroadcastReceiver will execute IntentService and handle Reponse
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            Log.i(CLASS_NAME,"Receive from Broadcast!");
            if (bundle != null) {
                int resultCode = bundle.getInt(IntentTestService.RESULT);
                int resultStatus = bundle.getInt(IntentTestService.STATUS);

                mProgressbar.setProgress(resultStatus);
                if (resultCode == RESULT_OK) {
                    Log.i(CLASS_NAME, "RESULT IS 100%, redirect to next Activity!");
                    Intent overviewIntent = new Intent(MainActivity.this, NextActivity.class);
                    startActivity(overviewIntent);
                }
            }
        }
    };

Bandscheibe und Sport

Nachdem mein Bandscheibenvorfall mittlerweile doch schon über 6 Monate her ist habe ich erfreuliche Nachrichten für euch. Mir geht es wieder halbwegs besser. Ich habe mein Arbeitsvolumen etwas reduziert und regelmäßig viel Sport gemacht und seit Ende 2013 vor allem am Crossfit regelmäßig teilgenommen. Es ist der Wahnsinn was für Fortschritte man macht und vor allem was der eigene Rücken leisten kann. Ich hätte mir nie träumen lassen das durch dieses intensive Training die Schmerzen wirklich besser werden. Ich lag falsch kann ich da nur sagen. Mit Unterstützung von Ralf Müller dem Crossfit Trainier der Crossfit Box in Kulmbach haben wir die Übungen für meinen Rücken skaliert und auch in den WODs konnte ich immer an mein Schmerzlimit gehen.

 

logo

 

Für alle die Crossfit ziemlich krass finden oder auch die Videos bei Youtube ansehen werden schnell sehen das es sich um ein richtig gute Training für den ganzen Körper geht. Alle Übungen sind skalierbar und können dem eigenen Aufbautrainig angepasst werden. Ein großes Erfolg von Crossfit ist auch die Gruppendynamic die sich entwickelt. Man trainiert oft mit den Gleichen und über die gegenseitige Motivation sorgt die Gruppe an sich, der Trainer und das ganze Klima beim Workout. Jeder gibt sein Bestes, jeder will besser werden und jeder will sich selbst an seine Grenzen bringen.

 

Ich weiß nicht ob es übertrieben klingt oder ob es der Wahrheit entspricht aber danke Crossfit kann ich mich wieder bewegen!

Raspberry PI armHF und Samsung

Zu meinem POST: raspberry-pi-als-druckerserver-mit-samsung-treibern

Leider eine schlechte Nachricht für alle Samsung Drucker Besitzer. Samsung hat mit seinem neuen Universal Treiber die installation auf den armhf unterbunden. Auch wenn man die Installationsscripte im umgeht und hinzufügt wird zwar der Drucker sauber installiert aber nicht durchgestartet. Er reagiert einfach nicht auf die eingehenden Signale.

Ich werde weiter versuchen eine lauffähige Variante zu erstellen.

Raspberry PI als VPN Server

Nachdem der Zwerg immer noch Power hat und kein Problem damit neben den bekannten Installationen auch noch als VPN Server zu agieren habe ich mich kurzerhand dazu entschlossen einen VPN aufzusetzen um ins Heimische Netzwerk zu gelangen. OpenVPN bietet hierfür eine super Möglickeit und eine ausführliche Anleitung findet ihr hier:

http://jankarres.de/2013/05/raspberry-pi-openvpn-vpn-server-installieren/

Einzig das gepackte .tar.gz Paket für den Client solltet ihr nochmal nachsehen. Mir ist aufgefallen das in der .ovpn alle Werte in einer Zeile abgespeichert wurden. Somit hatte ich ein Problem bei der erstmaligen Initialisierung.

dev tun
client
proto udp
remote dyndns.org 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
comp-lzo
verb 3

Sobald die Werte korrekt hinterlegt wurden solltet ihr ebenfalls die Portfreigabe an eurem Router hinterlegen. z.B. 1194 auf UDP Basis.
Viel Erfolg!