text:
package router

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"net"
	"sync"
	"syscall"
	"time"

	"github.com/pkg/errors"
	"github.com/vishvananda/netlink"
	"github.com/weaveworks/go-odp/odp"
	"github.com/weaveworks/mesh"

	"github.com/weaveworks/weave/net/ipsec"
)

// The virtual bridge accepts packets from ODP vports and the router
// port (i.e. InjectPacket).  We need a map key to index those
// possibilities:
type bridgePortID struct {
	vport  odp.VportID
	router bool
}

// A bridgeSender sends out a packet from the virtual bridge
type bridgeSender func(key PacketKey, lock *fastDatapathLock) FlowOp

// A missHandler handles an ODP miss
type missHandler func(fks odp.FlowKeys, lock *fastDatapathLock) FlowOp

type FastDatapath struct {
	lock             sync.Mutex // guards state and synchronises use of dpif
	iface            *net.Interface
	dpif             *odp.Dpif
	dp               odp.DatapathHandle
	deleteFlowsCount uint64
	missCount        uint64
	missHandlers     map[odp.VportID]missHandler
	localPeer        *mesh.Peer
	peers            *mesh.Peers
	overlayConsumer  OverlayConsumer
	ipsec            *ipsec.IPSec

	// Bridge state: How to send to the given bridge port
	sendToPort map[bridgePortID]bridgeSender

	// How to send to a given destination MAC
	sendToMAC map[MAC]bridgeSender

	// MACs seen on the bridge recently
	seenMACs map[MAC]struct{}

	// vxlan vports associated with the given UDP ports
	vxlanUDPPorts    map[int]odp.VportID
	vxlanVportIDs    map[odp.VportID]struct{}
	mainVxlanVportID odp.VportID
	mainVxlanUDPPort int

	// A singleton pool for the occasions when we need to decode
	// the packet.
	dec *EthernetDecoder

	// forwarders by remote peer
	forwarders map[mesh.PeerName]*fastDatapathForwarder
}

func NewFastDatapath(iface *net.Interface, port int, encryptionEnabled bool) (*FastDatapath, error) {
	var ipSec *ipsec.IPSec

	dpif, err := odp.NewDpif()
	if err != nil {
		return nil, err
	}

	success := false
	defer func() {
		if !success {
			dpif.Close()
		}
	}()

	dp, err := dpif.LookupDatapath(iface.Name)
	if err != nil {
		return nil, err
	}

	if encryptionEnabled {
		var err error
		if ipSec, err = ipsec.New(log); err != nil {
			return nil, errors.Wrap(err, "ipsec new")
		}
		if err := ipSec.Flush(false); err != nil {
			return nil, errors.Wrap(err, "ipsec flush")
		}
	}

	fastdp := &FastDatapath{
		iface:         iface,
		dpif:          dpif,
		dp:            dp,
		missHandlers:  make(map[odp.VportID]missHandler),
		ipsec:         ipSec,
		sendToPort:    nil,
		sendToMAC:     make(map[MAC]bridgeSender),
		seenMACs:      make(map[MAC]struct{}),
		vxlanUDPPorts: make(map[int]odp.VportID),
		vxlanVportIDs: make(map[odp.VportID]struct{}),
		forwarders:    make(map[mesh.PeerName]*fastDatapathForwarder),
	}

	// This delete happens asynchronously in the kernel, meaning that
	// we can sometimes fail to recreate the vxlan vport with EADDRINUSE -
	// consequently we retry a small number of times in
	// getVxlanVportIDHarder() to compensate.
	if err := fastdp.deleteVxlanVports(); err != nil {
		return nil, err
	}

	if err := fastdp.deleteFlows(); err != nil {
		return nil, err
	}

	// We use the weave port number plus 1 for vxlan.  Hard-coding
	// this relationship may seem dubious, but there is no moral
	// difference between this and requiring that the sleeve UDP
	// port number is the same as the TCP port number.  The hard
	// part would be not adding weaver flags to allow the port
	// numbers to be independent, but working out how to specify
	// them on the connecting side.  So we can wait to find out if
	// anyone wants that.
	fastdp.mainVxlanUDPPort = port + 1
	fastdp.mainVxlanVportID, err = fastdp.getVxlanVportIDHarder(fastdp.mainVxlanUDPPort, 5, time.Millisecond*10)
	if err != nil {
		return nil, err
	}

	// need to lock before we might receive events
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	if _, err := dp.ConsumeMisses(fastdp); err != nil {
		return nil, err
	}

	if _, err := dp.ConsumeVportEvents(fastdp); err != nil {
		return nil, err
	}

	vports, err := dp.EnumerateVports()
	if err != nil {
		return nil, err
	}

	for _, vport := range vports {
		fastdp.makeBridgeVport(vport)
	}

	success = true
	go fastdp.run()
	return fastdp, nil
}

func (fastdp *FastDatapath) Close() error {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()
	err := fastdp.dpif.Close()
	fastdp.dpif = nil
	return err
}

// While processing a packet, we can potentially acquire and drop the
// FastDatapath lock many times (acquiring it to acceess FastDatapath
// state, and invoke ODP operations; dropping it to invoke callbacks
// that may re-enter the FastDatapath).  A fastDatapathLock
// coordinates this process.
type fastDatapathLock struct {
	fastdp *FastDatapath
	locked bool

	// While the lock is dropped, deleteFlows could be called.  We
	// need to detect when this happens and avoid creating flows,
	// because they may be based on stale information.
	deleteFlowsCount uint64
}

func (fastdp *FastDatapath) startLock() fastDatapathLock {
	fastdp.lock.Lock()
	return fastDatapathLock{
		fastdp:           fastdp,
		locked:           true,
		deleteFlowsCount: fastdp.deleteFlowsCount,
	}
}

func (lock *fastDatapathLock) unlock() {
	if lock.locked {
		lock.fastdp.lock.Unlock()
		lock.locked = false
	}
}

func (lock *fastDatapathLock) relock() {
	if !lock.locked {
		lock.fastdp.lock.Lock()
		lock.locked = true
	}
}

// InjectorConsumer bits

type fastDatapathInjectorConsumer struct {
	*FastDatapath
}

func (fastdp *FastDatapath) InjectorConsumer() InjectorConsumer {
	return fastDatapathInjectorConsumer{fastdp}
}

func (fastdp fastDatapathInjectorConsumer) Interface() *net.Interface {
	return fastdp.iface
}

func (fastdp fastDatapathInjectorConsumer) String() string {
	return fmt.Sprint(fastdp.iface.Name, " (via ODP)")
}

func (fastdp fastDatapathInjectorConsumer) Stats() map[string]int {
	lock := fastdp.startLock()
	defer lock.unlock()

	return map[string]int{
		"FlowMisses": int(fastdp.missCount),
	}
}

var routerBridgePortID = bridgePortID{router: true}

func (fastdp fastDatapathInjectorConsumer) StartConsumingPackets(consumer Consumer) error {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	if fastdp.sendToPort[routerBridgePortID] != nil {
		return fmt.Errorf("FastDatapath already has a Consumer")
	}

	// set up delivery to the weave router port on the bridge
	fastdp.addSendToPort(routerBridgePortID,
		func(key PacketKey, lock *fastDatapathLock) FlowOp {
			// drop the FastDatapath lock in order to call
			// the consumer
			lock.unlock()
			return consumer(key)
		})
	return nil
}

func (fastdp fastDatapathInjectorConsumer) InjectPacket(key PacketKey) FlowOp {
	lock := fastdp.startLock()
	defer lock.unlock()
	return fastdp.bridge(routerBridgePortID, key, &lock)
}

// Ethernet bridge implementation

func (fastdp *FastDatapath) bridge(ingress bridgePortID, key PacketKey, lock *fastDatapathLock) FlowOp {
	lock.relock()
	if fastdp.sendToMAC[key.SrcMAC] == nil {
		// Learn the source MAC
		fastdp.sendToMAC[key.SrcMAC] = fastdp.sendToPort[ingress]
		fastdp.seenMACs[key.SrcMAC] = struct{}{}
	}

	// If we know about the destination MAC, deliver it to the
	// associated port.
	if sender := fastdp.sendToMAC[key.DstMAC]; sender != nil {
		return NewMultiFlowOp(false, odpEthernetFlowKey(key), sender(key, lock))
	}

	// Otherwise, it might be a real broadcast, or it might
	// be for a MAC we don't know about yet.  Either way, we'll
	// broadcast it.
	mfop := NewMultiFlowOp(false)

	if (key.DstMAC[0] & 1) == 0 {
		// Not a real broadcast, so don't create a flow rule.
		// If we did, we'd need to delete the flows every time
		// we learned a new MAC address, or have a more
		// complicated selective invalidation scheme.
		log.Debug("fastdp: unknown dst", ingress, key)
		mfop.Add(vetoFlowCreationFlowOp{})
	} else {
		// A real broadcast
		log.Debug("fastdp: broadcast", ingress, key)
		mfop.Add(odpEthernetFlowKey(key))
	}

	// Send to all ports except the one it came in on. The
	// sendToPort map is immutable, so it is safe to iterate over
	// it even though the sender functions can drop the
	// fastDatapathLock
	for id, sender := range fastdp.sendToPort {
		if id != ingress {
			mfop.Add(sender(key, lock))
		}
	}

	return mfop
}

// Overlay bits

type fastDatapathOverlay struct {
	*FastDatapath
}

func (fastdp *FastDatapath) Overlay() NetworkOverlay {
	return fastDatapathOverlay{fastdp}
}

func (fastdp fastDatapathOverlay) InvalidateRoutes() {
	log.Debug("InvalidateRoutes")
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()
	checkWarn(fastdp.deleteFlows())
}

func (fastdp fastDatapathOverlay) InvalidateShortIDs() {
	log.Debug("InvalidateShortIDs")
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()
	checkWarn(fastdp.deleteFlows())
}

func (fastdp fastDatapathOverlay) Stop() {
	if fastdp.ipsec != nil {
		if err := fastdp.ipsec.Flush(true); err != nil {
			log.Errorf("ipsec flush failed: %s", err)
		}
	}
}

func (fastDatapathOverlay) AddFeaturesTo(features map[string]string) {
	// Nothing needed.  Fast datapath support is indicated through
	// OverlaySwitch.
}

type FastDPStatus struct {
	Vports []VportStatus
	Flows  []FlowStatus
}

type FlowStatus odp.FlowInfo

func (flowStatus *FlowStatus) MarshalJSON() ([]byte, error) {
	type jsonFlowStatus struct {
		FlowKeys []string
		Actions  []string
		Packets  uint64
		Bytes    uint64
		Used     uint64
	}

	flowKeys := make([]string, 0, len(flowStatus.FlowKeys))
	for _, flowKey := range flowStatus.FlowKeys {
		if !flowKey.Ignored() {
			flowKeys = append(flowKeys, fmt.Sprint(flowKey))
		}
	}

	actions := make([]string, 0, len(flowStatus.Actions))
	for _, action := range flowStatus.Actions {
		actions = append(actions, fmt.Sprint(action))
	}

	return json.Marshal(&jsonFlowStatus{flowKeys, actions, flowStatus.Packets, flowStatus.Bytes, flowStatus.Used})
}

type VportStatus odp.Vport

func (vport *VportStatus) MarshalJSON() ([]byte, error) {
	type jsonVportStatus struct {
		ID       odp.VportID
		Name     string
		TypeName string
	}

	return json.Marshal(&jsonVportStatus{vport.ID, vport.Spec.Name(), vport.Spec.TypeName()})
}

func (fastdp fastDatapathOverlay) Diagnostics() interface{} {
	lock := fastdp.startLock()
	defer lock.unlock()

	vports, err := fastdp.dp.EnumerateVports()
	checkWarn(err)
	vportStatuses := make([]VportStatus, 0, len(vports))
	for _, vport := range vports {
		vportStatuses = append(vportStatuses, VportStatus(vport))
	}

	flows, err := fastdp.dp.EnumerateFlows()
	checkWarn(err)
	flowStatuses := make([]FlowStatus, 0, len(flows))
	for _, flow := range flows {
		flowStatuses = append(flowStatuses, FlowStatus(flow))
	}

	return FastDPStatus{
		vportStatuses,
		flowStatuses,
	}
}

type FastDPMetrics struct {
	Flows        int
	TotalPackets uint64
	TotalBytes   uint64
}

func (s FastDPStatus) Metrics() interface{} {
	var m FastDPMetrics
	m.Flows = len(s.Flows)
	for _, flow := range s.Flows {
		m.TotalPackets += flow.Packets
		m.TotalBytes += flow.Bytes
	}
	return &m
}

func (fastdp fastDatapathOverlay) StartConsumingPackets(localPeer *mesh.Peer, peers *mesh.Peers, consumer OverlayConsumer) error {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	if fastdp.overlayConsumer != nil {
		return fmt.Errorf("FastDatapath already has an OverlayConsumer")
	}

	fastdp.localPeer = localPeer
	fastdp.peers = peers
	fastdp.overlayConsumer = consumer
	return nil
}

func (fastdp *FastDatapath) getVxlanVportIDHarder(udpPort int, retries int, duration time.Duration) (odp.VportID, error) {
	var vxlanVportID odp.VportID
	var err error
	for try := 0; try < retries; try++ {
		vxlanVportID, err = fastdp.getVxlanVportID(udpPort)
		if err == nil || err != odp.NetlinkError(syscall.EADDRINUSE) {
			return vxlanVportID, err
		}
		log.Warning("Address already in use creating vxlan vport ", udpPort, " - retrying")
		time.Sleep(duration)
	}
	return 0, err
}

func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	if vxlanVportID, present := fastdp.vxlanUDPPorts[udpPort]; present {
		return vxlanVportID, nil
	}

	name := fmt.Sprintf("vxlan-%d", udpPort)
	vxlanVportID, err := fastdp.dp.CreateVport(
		odp.NewVxlanVportSpec(name, uint16(udpPort)))
	if err != nil {
		return 0, err
	}

	// If a netdev for the vxlan vport exists, we need to do an extra check
	// to bypass the kernel bug which makes the vxlan creation to complete
	// successfully regardless whether there were any errors when binding
	// to the given UDP port.
	if link, err := netlink.LinkByName(name); err == nil {
		if link.Attrs().Flags&net.FlagUp == 0 {
			// The netdev interface is down, so most likely bringing it up
			// has failed due to the UDP port being in use.
			if err := fastdp.dp.DeleteVport(vxlanVportID); err != nil {
				log.Warningf("Unable to remove vxlan vport %d: %s", vxlanVportID, err)
			}
			return 0, odp.NetlinkError(syscall.EADDRINUSE)
		}
	}

	fastdp.vxlanUDPPorts[udpPort] = vxlanVportID
	fastdp.vxlanVportIDs[vxlanVportID] = struct{}{}
	fastdp.missHandlers[vxlanVportID] = func(fks odp.FlowKeys, lock *fastDatapathLock) FlowOp {
		log.Debug("ODP miss: ", fks, " on port ", vxlanVportID)
		tunnel := fks[odp.OVS_KEY_ATTR_TUNNEL].(odp.TunnelFlowKey)
		tunKey := tunnel.Key()

		lock.relock()
		consumer := fastdp.overlayConsumer
		if consumer == nil {
			return vetoFlowCreationFlowOp{}
		}

		srcPeer, dstPeer := fastdp.extractPeers(tunKey.TunnelId)
		if srcPeer == nil || dstPeer == nil {
			return vetoFlowCreationFlowOp{}
		}

		lock.unlock()
		pk := flowKeysToPacketKey(fks)
		var zeroMAC MAC
		if pk.SrcMAC == zeroMAC && pk.DstMAC == zeroMAC {
			return vxlanSpecialPacketFlowOp{
				fastdp:  fastdp,
				srcPeer: srcPeer,
				sender: &net.UDPAddr{
					IP:   net.IP(tunKey.Ipv4Src[:]),
					Port: udpPort,
				},
			}
		}

		key := ForwardPacketKey{
			SrcPeer:   srcPeer,
			DstPeer:   dstPeer,
			PacketKey: pk,
		}

		var tunnelFlowKey odp.TunnelFlowKey
		tunnelFlowKey.SetTunnelId(tunKey.TunnelId)
		tunnelFlowKey.SetIpv4Src(tunKey.Ipv4Src)
		tunnelFlowKey.SetIpv4Dst(tunKey.Ipv4Dst)

		return NewMultiFlowOp(false, odpFlowKey(tunnelFlowKey), consumer(key))
	}

	return vxlanVportID, nil
}

func (fastdp *FastDatapath) extractPeers(tunnelID [8]byte) (*mesh.Peer, *mesh.Peer) {
	vni := binary.BigEndian.Uint64(tunnelID[:])
	srcPeer := fastdp.peers.FetchByShortID(mesh.PeerShortID(vni & 0xfff))
	dstPeer := fastdp.peers.FetchByShortID(mesh.PeerShortID((vni >> 12) & 0xfff))
	return srcPeer, dstPeer
}

type vxlanSpecialPacketFlowOp struct {
	NonDiscardingFlowOp
	fastdp  *FastDatapath
	srcPeer *mesh.Peer
	sender  *net.UDPAddr
}

func (op vxlanSpecialPacketFlowOp) Process(frame []byte, dec *EthernetDecoder, broadcast bool) {
	op.fastdp.lock.Lock()
	fwd := op.fastdp.forwarders[op.srcPeer.Name]
	op.fastdp.lock.Unlock()

	if fwd != nil && dec.IsSpecial() {
		fwd.handleVxlanSpecialPacket(frame, op.sender)
	}
}

type fastDatapathForwarder struct {
	fastdp         *FastDatapath
	remotePeer     *mesh.Peer
	localIP        [4]byte
	sendControlMsg func(byte, []byte) error
	connUID        uint64
	vxlanVportID   odp.VportID

	sessionKey                 *[32]byte
	isEncrypted                bool
	isOutboundIPSecEstablished bool

	lock              sync.RWMutex
	confirmed         bool
	remoteAddr        *net.UDPAddr
	heartbeatInterval time.Duration
	heartbeatTimer    *time.Timer // for sending
	heartbeatTimeout  *time.Timer // for receiving
	ackedHeartbeat    bool
	stopChan          chan struct{}
	stopped           bool
	healthy           bool
	established       bool
	establishedChan   chan struct{}
	errorChan         chan error
	healthChan        chan bool
}

func (fastdp fastDatapathOverlay) PrepareConnection(params mesh.OverlayConnectionParams) (mesh.OverlayConnection, error) {
	vxlanVportID := fastdp.mainVxlanVportID
	vxlanUDPPort := fastdp.mainVxlanUDPPort

	remoteAddr := makeUDPAddr(params.RemoteAddr)
	if params.Outbound {
		var err error
		// The provided address contains the main weave port
		// number to connect to.  We need to derive the vxlan
		// port number from that.
		vxlanRemoteAddr := *remoteAddr
		vxlanRemoteAddr.Port++
		remoteAddr = &vxlanRemoteAddr
		vxlanUDPPort = remoteAddr.Port
		vxlanVportID, err = fastdp.getVxlanVportID(vxlanUDPPort)
		if err != nil {
			return nil, err
		}
	} else {
		remoteAddr.Port = vxlanUDPPort
	}

	localIP, err := ipv4Bytes(params.LocalAddr.IP)
	if err != nil {
		return nil, err
	}

	fwd := &fastDatapathForwarder{
		fastdp:         fastdp.FastDatapath,
		remotePeer:     params.RemotePeer,
		localIP:        localIP,
		sendControlMsg: params.SendControlMessage,
		connUID:        params.ConnUID,
		vxlanVportID:   vxlanVportID,
		sessionKey:     params.SessionKey,
		healthy:        true,

		remoteAddr:        remoteAddr,
		heartbeatInterval: FastHeartbeat,
		stopChan:          make(chan struct{}),

		establishedChan: make(chan struct{}),
		errorChan:       make(chan error, 1),
		healthChan:      make(chan bool),
	}

	return fwd, nil
}

func ipv4Bytes(ip net.IP) (res [4]byte, err error) {
	ipv4 := ip.To4()
	if ipv4 != nil {
		copy(res[:], ipv4)
	} else {
		err = fmt.Errorf("IP address %s is not IPv4", ip)
	}
	return
}

func (fwd *fastDatapathForwarder) logPrefix() string {
	return fmt.Sprintf("fastdp ->[%s|%s]: ", fwd.remoteAddr, fwd.remotePeer)
}

func (fwd *fastDatapathForwarder) Confirm() {
	fwd.lock.Lock()

	if fwd.confirmed {
		log.Fatal(fwd.logPrefix(), "already confirmed")
	}

	var controlMsg []byte
	if fwd.fastdp.ipsec != nil && fwd.sessionKey != nil {
		fwd.isEncrypted = true
		log.Info("Setting up IPsec between ", fwd.fastdp.localPeer, " and ", fwd.remotePeer)
		var err error
		controlMsg, err = fwd.fastdp.ipsec.InitSALocal(
			fwd.fastdp.localPeer.Name, fwd.remotePeer.Name, fwd.connUID,
			net.IP(fwd.localIP[:]), fwd.remoteAddr.IP,
			fwd.remoteAddr.Port,
			fwd.sessionKey,
		)
		if err != nil {
			log.Error(fwd.logPrefix(), "ipsec init SA local failed: ", err)
			fwd.handleError(err)
			fwd.lock.Unlock()
			return
		}
	}

	log.Debug(fwd.logPrefix(), "confirmed")
	fwd.fastdp.addForwarder(fwd.remotePeer.Name, fwd)
	fwd.confirmed = true

	if fwd.remoteAddr != nil && (!fwd.isEncrypted || fwd.isOutboundIPSecEstablished) {
		// have the goroutine send a heartbeat straight away
		fwd.heartbeatTimer = time.NewTimer(0)
	} else {
		// we'll reset the timer when we learn the remote ip
		fwd.heartbeatTimer = time.NewTimer(MaxDuration)
	}

	fwd.heartbeatTimeout = time.NewTimer(HeartbeatTimeout)

	fwd.lock.Unlock() // unlock before calling send() which may block

	if len(controlMsg) > 0 {
		if err := fwd.sendControlMsg(FastDatapathCryptoInitSARemote, controlMsg); err != nil {
			log.Error(fwd.logPrefix(), "ipsec send InitSARemote failed: ", err)
			fwd.handleError(err)
			return
		}
	}

	go fwd.doHeartbeats()
}

func (fwd *fastDatapathForwarder) EstablishedChannel() <-chan struct{} {
	return fwd.establishedChan
}

func (fwd *fastDatapathForwarder) ErrorChannel() <-chan error {
	return fwd.errorChan
}

func (fwd *fastDatapathForwarder) HealthChannel() <-chan bool {
	return fwd.healthChan
}

func (fwd *fastDatapathForwarder) doHeartbeats() {
	var err error
	for err == nil {
		select {
		case <-fwd.heartbeatTimer.C:
			if fwd.confirmed {
				log.Debug(fwd.logPrefix(), "sending Heartbeat to peer")
				fwd.sendHeartbeat()
			}
			fwd.heartbeatTimer.Reset(fwd.heartbeatInterval)

		case <-fwd.heartbeatTimeout.C:
			log.Debug(fwd.logPrefix(), "missed Heartbeat from peer, marking fastdp forwarder as un-healthy")

			// treat missed heartbeat as transient error. Indicate to overlay forwarder
			// that Forwarder is un-healthy so it can pick next best forwarder
			fwd.healthChan <- false

			// switch from fast-heartbeat to slow-heartbeat to avoid aggressive heartbeats
			// when there is no estbalished session with peer yet
			if fwd.heartbeatInterval != SlowHeartbeat {
				fwd.heartbeatInterval = SlowHeartbeat
				if fwd.heartbeatTimer != nil {
					fwd.heartbeatTimer.Reset(fwd.heartbeatInterval)
				}
			}

			if fwd.healthy {
				fwd.healthy = false
			}

		case <-fwd.stopChan:
			return
		}
	}

	fwd.lock.Lock()
	defer fwd.lock.Unlock()
	fwd.handleError(err)
}

// Handle an error which leads to notifying the listener and
// termination of the forwarder
func (fwd *fastDatapathForwarder) handleError(err error) {
	if err == nil {
		return
	}

	select {
	case fwd.errorChan <- err:
	default:
	}

	// stop the heartbeat goroutine
	if !fwd.stopped {
		fwd.stopped = true
		close(fwd.stopChan)
	}
}

func (fwd *fastDatapathForwarder) sendHeartbeat() {
	fwd.lock.RLock()

	// the heartbeat payload consists of the 64-bit connection uid
	// followed by the 16-bit packet size.
	buf := make([]byte, EthernetOverhead+fwd.fastdp.iface.MTU)
	binary.BigEndian.PutUint64(buf[EthernetOverhead:], fwd.connUID)
	binary.BigEndian.PutUint16(buf[EthernetOverhead+8:], uint16(len(buf)))

	dec := NewEthernetDecoder()
	dec.DecodeLayers(buf)
	pk := ForwardPacketKey{
		PacketKey: dec.PacketKey(),
		SrcPeer:   fwd.fastdp.localPeer,
		DstPeer:   fwd.remotePeer,
	}
	fwd.lock.RUnlock()

	if fop := fwd.Forward(pk); fop != nil {
		fop.Process(buf, dec, false)
	}
}

const (
	FastDatapathHeartbeatAck = iota
	FastDatapathCryptoInitSARemote
)

func (fwd *fastDatapathForwarder) handleVxlanSpecialPacket(frame []byte, sender *net.UDPAddr) {
	fwd.lock.Lock()
	defer fwd.lock.Unlock()

	log.Debug(fwd.logPrefix(), "handleVxlanSpecialPacket")

	// the only special packet type is a heartbeat
	if len(frame) < EthernetOverhead+10 {
		log.Warning(fwd.logPrefix(), "short vxlan special packet: ", len(frame), " bytes")
		return
	}

	if binary.BigEndian.Uint64(frame[EthernetOverhead:]) != fwd.connUID ||
		uint16(len(frame)) != binary.BigEndian.Uint16(frame[EthernetOverhead+8:]) {
		return
	}

	if fwd.remoteAddr == nil {
		fwd.remoteAddr = sender

		if fwd.confirmed {
			fwd.heartbeatTimer.Reset(0)
		}
	} else if !udpAddrsEqual(fwd.remoteAddr, sender) {
		log.Info(fwd.logPrefix(), "Peer IP address changed to ", sender)
		fwd.remoteAddr = sender
	}

	if !fwd.ackedHeartbeat {
		fwd.ackedHeartbeat = true
		log.Debug(fwd.logPrefix(), "Ack Heartbeat from peer")
		fwd.handleError(fwd.sendControlMsg(FastDatapathHeartbeatAck, nil))
	} else {
		log.Debug(fwd.logPrefix(), "Got Heartbeat Ack from peer")
	}

	// we can receive a heartbeat before Confirm() has set up
	// heartbeatTimeout
	if fwd.heartbeatTimeout != nil {
		fwd.heartbeatTimeout.Reset(HeartbeatTimeout)
		if !fwd.healthy {
			// If fastdp was marked as unhealthy earlier due to missed heartbeat then indicate to
			// overlay forwarder that Forwarder is healthy now so it can pick next best forwarder
			log.Debug(fwd.logPrefix(), "got Heartbeat from peer, marking fastdp forwarder as healthy")
			fwd.healthy = true
			fwd.healthChan <- true
		}
	}
}

func (fwd *fastDatapathForwarder) ControlMessage(tag byte, msg []byte) {
	fwd.lock.Lock()
	defer fwd.lock.Unlock()

	switch tag {
	case FastDatapathHeartbeatAck:
		fwd.handleHeartbeatAck()
	case FastDatapathCryptoInitSARemote:
		fwd.handleCryptoInitSARemote(msg)

	default:
		log.Info(fwd.logPrefix(), "Ignoring unknown control message: ", tag)
	}
}

func (fwd *fastDatapathForwarder) Attrs() map[string]interface{} {
	return map[string]interface{}{"name": "fastdp", "mtu": fwd.fastdp.iface.MTU}
}

func (fwd *fastDatapathForwarder) handleHeartbeatAck() {
	log.Debug(fwd.logPrefix(), "handleHeartbeatAck")

	if !fwd.established {
		close(fwd.establishedChan)
		fwd.established = true
	}

	if fwd.heartbeatInterval != SlowHeartbeat {
		fwd.heartbeatInterval = SlowHeartbeat
		if fwd.heartbeatTimer != nil {
			fwd.heartbeatTimer.Reset(fwd.heartbeatInterval)
		}
	}
}

func (fwd *fastDatapathForwarder) handleCryptoInitSARemote(msg []byte) {
	if fwd.stopped {
		log.Info(fwd.logPrefix(), "IPSec init SA remote failed: forwarder has already been stopped")
		return
	}

	log.Info(fwd.logPrefix(), "IPSec init SA remote")
	err := fwd.fastdp.ipsec.InitSARemote(
		msg,
		fwd.fastdp.localPeer.Name, fwd.remotePeer.Name, fwd.connUID,
		net.IP(fwd.localIP[:]), fwd.remoteAddr.IP, fwd.remoteAddr.Port,
		fwd.sessionKey,
	)
	if err != nil {
		log.Warning(fwd.logPrefix(), "IPSec init SA remote failed: ", err)
		fwd.handleError(err)
		return
	}

	// FastDatapathCryptoInitSARemote can be received before Confirm'ing
	// connection, thus before InitSALocal.
	if fwd.confirmed && !fwd.isOutboundIPSecEstablished {
		fwd.isOutboundIPSecEstablished = true
		fwd.heartbeatTimer.Reset(0)
	}
}

func (fwd *fastDatapathForwarder) Forward(key ForwardPacketKey) FlowOp {
	if !key.SrcPeer.HasShortID || !key.DstPeer.HasShortID {
		return nil
	}

	fwd.lock.RLock()
	defer fwd.lock.RUnlock()

	if fwd.remoteAddr == nil {
		// Returning a DiscardingFlowOp would discard the
		// packet, but also result in a flow rule, which we
		// would have to invalidate when we learn the remote
		// IP.  So for now, just prevent flows.
		return vetoFlowCreationFlowOp{}
	}

	remoteIP, err := ipv4Bytes(fwd.remoteAddr.IP)
	if err != nil {
		log.Error(err)
		return DiscardingFlowOp{}
	}

	var sta odp.SetTunnelAction
	sta.SetTunnelId(tunnelIDFor(key))
	sta.SetIpv4Src(fwd.localIP)
	sta.SetIpv4Dst(remoteIP)
	sta.SetTos(0)
	sta.SetTtl(64)
	sta.SetDf(true)
	sta.SetCsum(false)
	return fwd.fastdp.odpActions(sta, odp.NewOutputAction(fwd.vxlanVportID))
}

func tunnelIDFor(key ForwardPacketKey) (tunnelID [8]byte) {
	src := uint64(key.SrcPeer.ShortID)
	dst := uint64(key.DstPeer.ShortID)
	binary.BigEndian.PutUint64(tunnelID[:], src|dst<<12)
	return
}

func (fwd *fastDatapathForwarder) Stop() {
	// Might be nice to delete all the relevant flows here, but we
	// can just let them expire.
	fwd.fastdp.removeForwarder(fwd.remotePeer.Name, fwd)

	fwd.lock.Lock()
	defer fwd.lock.Unlock()
	fwd.sendControlMsg = func(byte, []byte) error { return nil }

	if fwd.isEncrypted {
		localIP := net.IP(fwd.localIP[:])
		log.Info("Destroying IPsec between ", fwd.fastdp.localPeer, " and ", fwd.remotePeer)
		err := fwd.fastdp.ipsec.Destroy(
			fwd.fastdp.localPeer.Name, fwd.remotePeer.Name, fwd.connUID,
			localIP, fwd.remoteAddr.IP, fwd.remoteAddr.Port,
		)
		if err != nil {
			log.Errorf("ipsec destroy failed: %s", err)
		}
	}

	// stop the heartbeat goroutine
	if !fwd.stopped {
		fwd.stopped = true
		close(fwd.stopChan)
	}
}

func (fastdp *FastDatapath) addForwarder(peer mesh.PeerName, fwd *fastDatapathForwarder) {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	// We shouldn't have two confirmed forwarders to the same
	// remotePeer, due to the checks in LocalPeer AddConnection.
	fastdp.forwarders[peer] = fwd
}

func (fastdp *FastDatapath) removeForwarder(peer mesh.PeerName, fwd *fastDatapathForwarder) {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()
	if fastdp.forwarders[peer] == fwd {
		delete(fastdp.forwarders, peer)
	}
}

func (fastdp *FastDatapath) deleteFlows() error {
	fastdp.deleteFlowsCount++

	flows, err := fastdp.dp.EnumerateFlows()
	if err != nil {
		return err
	}

	for _, flow := range flows {
		err = fastdp.dp.DeleteFlow(flow.FlowKeys)
		if err != nil && !odp.IsNoSuchFlowError(err) {
			return err
		}
	}

	return nil
}

func (fastdp *FastDatapath) deleteVxlanVports() error {
	vports, err := fastdp.dp.EnumerateVports()
	if err != nil {
		return err
	}

	for _, vport := range vports {
		if vport.Spec.TypeName() != "vxlan" {
			continue
		}

		err = fastdp.dp.DeleteVport(vport.ID)
		if err != nil && !odp.IsNoSuchVportError(err) {
			return err
		}
	}

	return nil
}

func (fastdp *FastDatapath) run() {
	expireMACsCh := time.Tick(10 * time.Minute)
	expireFlowsCh := time.Tick(5 * time.Minute)

	for {
		select {
		case <-expireMACsCh:
			fastdp.expireMACs()

		case <-expireFlowsCh:
			fastdp.expireFlows()
		}
	}
}

func (fastdp *FastDatapath) expireMACs() {
	lock := fastdp.startLock()
	defer lock.unlock()

	for mac := range fastdp.sendToMAC {
		if _, present := fastdp.seenMACs[mac]; !present {
			delete(fastdp.sendToMAC, mac)
		}
	}

	fastdp.seenMACs = make(map[MAC]struct{})
}

func (fastdp *FastDatapath) expireFlows() {
	lock := fastdp.startLock()
	defer lock.unlock()

	flows, err := fastdp.dp.EnumerateFlows()
	checkWarn(err)

	for _, flow := range flows {
		if flow.Used == 0 {
			log.Debug("Expiring flow ", flow.FlowSpec)
			err = fastdp.dp.DeleteFlow(flow.FlowKeys)
		} else {
			fastdp.touchFlow(flow.FlowKeys, &lock)
			err = fastdp.dp.ClearFlow(flow.FlowSpec)
		}

		if err != nil && !odp.IsNoSuchFlowError(err) {
			log.Warn(err)
		}
	}
}

// The router needs to know which flows are active in order to
// maintain its MAC->peer table.  We do this by querying the router
// without an actual packet being involved.  Maybe it's
// worth devising a more unified approach in the future.
func (fastdp *FastDatapath) touchFlow(fks odp.FlowKeys, lock *fastDatapathLock) {
	// All the flows we create should have an ingress key, but we
	// check here just in case we encounter one from somewhere
	// else.
	ingressKey, present := fks[odp.OVS_KEY_ATTR_IN_PORT]
	if present {
		ingress := ingressKey.(odp.InPortFlowKey).VportID()
		handler := fastdp.getMissHandler(ingress)
		if handler != nil {
			handler(fks, lock)
			lock.relock()
		}
	}
}

func (fastdp *FastDatapath) Error(err error, stopped bool) {
	if stopped {
		log.Fatal("Error while listeniing on ODP datapath: ", err)
	}

	log.Error("Error while listening on ODP datapath: ", err)
}

func (fastdp *FastDatapath) Miss(packet []byte, fks odp.FlowKeys) error {
	ingress := fks[odp.OVS_KEY_ATTR_IN_PORT].(odp.InPortFlowKey).VportID()

	lock := fastdp.startLock()
	defer lock.unlock()

	fastdp.missCount++

	handler := fastdp.getMissHandler(ingress)
	if handler == nil {
		log.Debug("ODP miss (no handler): ", fks, " on port ", ingress)
		return nil
	}

	// Always include the ingress vport in the flow key.  While
	// this is not strictly necessary in some cases (e.g. for
	// delivery to a local netdev based on the dest MAC),
	// including the ingress in every flow makes things simpler
	// in touchFlow.
	mfop := NewMultiFlowOp(false, handler(fks, &lock), odpFlowKey(odp.NewInPortFlowKey(ingress)))
	fastdp.send(mfop, packet, &lock)
	return nil
}

func (fastdp *FastDatapath) getMissHandler(ingress odp.VportID) missHandler {
	handler := fastdp.missHandlers[ingress]
	if handler == nil {
		vport, err := fastdp.dp.LookupVport(ingress)
		if err != nil {
			log.Error(err)
			return nil
		}

		fastdp.makeBridgeVport(vport)
	}

	return handler
}

func (fastdp *FastDatapath) VportCreated(dpid odp.DatapathID, vport odp.Vport) error {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	if _, present := fastdp.missHandlers[vport.ID]; !present {
		fastdp.makeBridgeVport(vport)
	}

	return nil
}

func (fastdp *FastDatapath) VportDeleted(dpid odp.DatapathID, vport odp.Vport) error {
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()

	// there might be flow rules that still refer to the id of
	// this vport.  But we just allow them to expire.  Unless we
	// want prompt migration of MAC addresses, that should be
	// fine.
	delete(fastdp.missHandlers, vport.ID)
	fastdp.deleteSendToPort(bridgePortID{vport: vport.ID})
	return nil
}

func (fastdp *FastDatapath) makeBridgeVport(vport odp.Vport) {
	// Set up a bridge port for netdev and internal vports.  vxlan
	// vports are handled separately, as they do not correspond to
	// bridge ports (we set up the miss handler for them in
	// getVxlanVportID).
	typ := vport.Spec.TypeName()
	if typ != "netdev" && typ != "internal" {
		return
	}

	vportID := vport.ID

	// Sending to the bridge port outputs on the vport:
	fastdp.addSendToPort(bridgePortID{vport: vportID},
		func(_ PacketKey, _ *fastDatapathLock) FlowOp {
			return fastdp.odpActions(odp.NewOutputAction(vportID))
		})

	// Delete flows, in order to recalculate flows for broadcasts
	// on the bridge.
	checkWarn(fastdp.deleteFlows())

	// Packets coming from the netdev are processed by the bridge
	fastdp.missHandlers[vportID] = func(flowKeys odp.FlowKeys, lock *fastDatapathLock) FlowOp {
		return fastdp.bridge(bridgePortID{vport: vportID}, flowKeysToPacketKey(flowKeys), lock)
	}
}

func flowKeysToPacketKey(fks odp.FlowKeys) PacketKey {
	eth := fks[odp.OVS_KEY_ATTR_ETHERNET].(odp.EthernetFlowKey).Key()
	return PacketKey{SrcMAC: eth.EthSrc, DstMAC: eth.EthDst}
}

// The sendToPort map is read-only, so this method does the copy in
// order to add an entry.
func (fastdp *FastDatapath) addSendToPort(portID bridgePortID, sender bridgeSender) {
	sendToPort := map[bridgePortID]bridgeSender{portID: sender}
	for id, sender := range fastdp.sendToPort {
		sendToPort[id] = sender
	}
	fastdp.sendToPort = sendToPort
}

func (fastdp *FastDatapath) deleteSendToPort(portID bridgePortID) {
	sendToPort := make(map[bridgePortID]bridgeSender)
	for id, sender := range fastdp.sendToPort {
		if id != portID {
			sendToPort[id] = sender
		}
	}
	fastdp.sendToPort = sendToPort
}

// Send a packet, creating a corresponding ODP flow rule if possible
func (fastdp *FastDatapath) send(fops FlowOp, frame []byte, lock *fastDatapathLock) {
	// Gather the actions from actionFlowOps, execute any others
	var dec *EthernetDecoder
	flow := odp.NewFlowSpec()
	createFlow := true

	for _, xfop := range FlattenFlowOp(fops) {
		switch fop := xfop.(type) {
		case interface {
			updateFlowSpec(*odp.FlowSpec)
		}:
			fop.updateFlowSpec(&flow)
		case vetoFlowCreationFlowOp:
			createFlow = false
		default:
			if xfop.Discards() {
				continue
			}

			// A foreign FlowOp (e.g. a sleeve forwarding
			// FlowOp), so send the packet through the
			// FlowOp interface, decoding the packet
			// lazily.
			if dec == nil {
				dec = fastdp.takeDecoder(lock)
				dec.DecodeLayers(frame)

				// If we are sending the packet
				// through the FlowOp interface, we
				// mustn't create a flow, as that
				// could prevent the proper handling
				// of similar packets in the future.
				createFlow = false
			}

			if len(dec.decoded) != 0 {
				lock.unlock()
				fop.Process(frame, dec, false)
			}
		}
	}

	if fastdp.isHairpinFlow(&flow) {
		log.Warning("Vetoed installation of hairpin flow ", flow)
		return
	}

	if dec != nil {
		// put the decoder back
		lock.relock()
		fastdp.dec = dec
	}

	if len(flow.Actions) != 0 {
		lock.relock()
		checkWarn(fastdp.dp.Execute(frame, nil, flow.Actions))
	}

	if createFlow {
		lock.relock()
		// if the fastdp's deleteFlowsCount changed since we
		// initially locked it, then we might have created a
		// flow on the basis of stale information.  It's fine
		// to handle one packet like that, but it would be bad
		// to introduce a stale flow.
		if lock.deleteFlowsCount == fastdp.deleteFlowsCount {
			log.Debug("Creating ODP flow ", flow)
			checkWarn(fastdp.dp.CreateFlow(flow))
		}
	}
}

// Get the EthernetDecoder from the singleton pool
func (fastdp *FastDatapath) takeDecoder(lock *fastDatapathLock) *EthernetDecoder {
	lock.relock()
	dec := fastdp.dec
	if dec == nil {
		dec = NewEthernetDecoder()
	} else {
		fastdp.dec = nil
	}
	return dec
}

// A isHairpinFlow checks whether the flow is created due to enabled hairpin
// mode on the weave bridge port which attaches the datapath. Such flow is
// identified by either:
//
// * in_port == out_port, where in_port is non-vxlan vport;
// * a packet is sent back to a vxlan tunnel it has been received from and
//   the tunnel id is either the same or dstPeer and srcPeer are reversed.
func (fastdp *FastDatapath) isHairpinFlow(flow *odp.FlowSpec) bool {
	var (
		vxlanKey odp.TunnelAttrs
		inVport  odp.VportID
		inVxlan  bool
	)

	for _, key := range flow.FlowKeys {
		switch k := key.(type) {
		case odp.InPortFlowKey:
			inVport = k.VportID()
		case odp.TunnelFlowKey:
			inVxlan = true
			vxlanKey = k.Key()
		}
	}

	for _, action := range flow.Actions {
		switch a := action.(type) {
		case odp.SetTunnelAction:
			if inVxlan && a.TunnelAttrs.TunnelId == vxlanKey.TunnelId &&
				a.TunnelAttrs.Ipv4Src == vxlanKey.Ipv4Dst &&
				a.TunnelAttrs.Ipv4Dst == vxlanKey.Ipv4Src {
				return true
			}
		case odp.OutputAction:
			if a.VportID() == inVport {
				if _, ok := fastdp.vxlanVportIDs[a.VportID()]; !ok {
					return true
				}
			}
		}
	}

	return false
}

type odpActionsFlowOp struct {
	NonDiscardingFlowOp
	fastdp  *FastDatapath
	actions []odp.Action
}

func (fastdp *FastDatapath) odpActions(actions ...odp.Action) FlowOp {
	return odpActionsFlowOp{
		fastdp:  fastdp,
		actions: actions,
	}
}

func (fop odpActionsFlowOp) updateFlowSpec(flow *odp.FlowSpec) {
	flow.AddActions(fop.actions)
}

func (fop odpActionsFlowOp) Process(frame []byte, dec *EthernetDecoder, broadcast bool) {
	fastdp := fop.fastdp
	fastdp.lock.Lock()
	defer fastdp.lock.Unlock()
	checkWarn(fastdp.dp.Execute(frame, nil, fop.actions))
}

// A vetoFlowCreationFlowOp flags that no flow should be created
type vetoFlowCreationFlowOp struct {
	DiscardingFlowOp
}

// A odpFlowKeyFlowOp adds a FlowKey to the resulting flow
type odpFlowKeyFlowOp struct {
	DiscardingFlowOp
	key odp.FlowKey
}

func odpFlowKey(key odp.FlowKey) FlowOp {
	return odpFlowKeyFlowOp{key: key}
}

func (fop odpFlowKeyFlowOp) updateFlowSpec(flow *odp.FlowSpec) {
	flow.AddKey(fop.key)
}

func odpEthernetFlowKey(key PacketKey) FlowOp {
	fk := odp.NewEthernetFlowKey()
	fk.SetEthSrc(key.SrcMAC)
	fk.SetEthDst(key.DstMAC)
	return odpFlowKeyFlowOp{key: fk}
}

redpajama_set_name: RedPajamaGithub


text:
.timer on
.mode csv
.output elements.csv

select "Year", "Set Count", "Color", "Part", "Part ID", "Color ID";

select min(year), sum(1), colors.name, parts.name, parts.part_num, colors.id from sets
  join inventories
    on inventories.set_num = sets.set_num
   and inventories.version = 1
  left join inventory_parts
    on inventory_parts.inventory_id = inventories.id
  join parts
    on parts.part_num = inventory_parts.part_num
  join colors
    on colors.id = inventory_parts.color_id
 where (
        sets.set_num glob '[0-9][0-9][0-9][0-9][0-9]-[0-9]'
        or sets.set_num glob '[0-9][0-9][0-9][0-9]-[0-9]'
        or sets.set_num glob '[0-9][0-9][0-9]-[0-9]'
       )
 group by colors.name, parts.name, parts.part_num, colors.id
 order by year desc, colors.name asc


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.eastrivervillage.epic.VideoPlayerActivity"
    android:background="@color/card_bg_color">

    <com.devbrackets.android.exomedia.ui.widget.VideoView
        android:id="@+id/video_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>


text:
<?php
namespace Lemon\BernardBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class HelloCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('demo:hello')
            ->setDescription('Say hello')
            ->addArgument(
                'name',
                InputArgument::OPTIONAL,
                'Who do you want to say hello to?'
            )
            ->addOption(
               'yell',
               null,
               InputOption::VALUE_NONE,
               'If set, the task will yell in uppercase letters'
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getArgument('name');

        if ($name) {
            $text = 'Hello '.$name;
        } else {
            $text = 'Hello';
        }

        if ($input->getOption('yell')) {
            $text = strtoupper($text);
        }

        $output->writeln($text);

        $this->getContainer()->get('logger')->info($text);
    }
}


text:
$(document).ready(function(){
	$('#timezone').change( function(){
		var post = $( '#timezone' ).serialize();
		$.post( OC.filePath('calendar', 'ajax/settings', 'settimezone.php'), post, function(data){return;});
		return false;
	});
	$('#timeformat').change( function(){
		var data = $('#timeformat').serialize();
		$.post( OC.filePath('calendar', 'ajax/settings', 'settimeformat.php'), data, function(data){
			if(data == 'error'){
				console.log('saving timeformat failed');
			}
		});
	});
	$('#firstday').change( function(){
		var data = $('#firstday').serialize();
		$.post( OC.filePath('calendar', 'ajax/settings', 'setfirstday.php'), data, function(data){
			if(data == 'error'){
				console.log('saving firstday failed');
			}
		});
	});
	$('#timezonedetection').change( function(){
		var post = $('#timezonedetection').serialize();
		$.post( OC.filePath('calendar', 'ajax/settings', 'timezonedetection.php'), post, function(data){

		});
	});
	$.getJSON(OC.filePath('calendar', 'ajax/settings', 'timeformat.php'), function(jsondata, status) {
		$('#' + jsondata.timeformat).attr('selected',true);
		$('#timeformat_chzn').css('width', '100px');
	});
	$.getJSON(OC.filePath('calendar', 'ajax/settings', 'gettimezonedetection.php'), function(jsondata, status){
		if(jsondata.detection == 'true'){
			$('#timezonedetection').attr('checked', 'checked');
		}
	});
	$.getJSON(OC.filePath('calendar', 'ajax/settings', 'getfirstday.php'), function(jsondata, status) {
		$('#' + jsondata.firstday).attr('selected',true);
		$('#firstday_chzn').css('width', '100px');
	});
	$('#cleancalendarcache').click(function(){
		$.getJSON(OC.filePath('calendar', 'ajax/cache', 'rescan.php'), function(){
			calendarcachecheck();
		});
	});
	calendarcachecheck();

});
function calendarcachecheck(){
	$.getJSON(OC.filePath('calendar', 'ajax/cache', 'status.php'), function(jsondata, status) {
		$('#cleancalendarcache').attr('title', jsondata.l10n.text);
		if(jsondata.status == 'success'){
			$('#cleancalendarcache').css('background', '#F8F8F8');
			$('#cleancalendarcache').css('color', '#333');
			$('#cleancalendarcache').css('text-shadow', '#fff 0 1px 0');
		}else{
			$('#cleancalendarcache').css('background', '#DC143C');
			$('#cleancalendarcache').css('color', '#FFFFFF');
			$('#cleancalendarcache').css('text-shadow', '0px 0px 0px #fff, 0px 0px #fff');
		}
	});
}
OC.Share.loadIcons('calendar');


text:
package com.safecharge.model;

import javax.validation.constraints.Size;

import com.safecharge.util.Constants;
import com.safecharge.util.ValidChecksum;

@ValidChecksum(orderMappingName = Constants.ChecksumOrderMapping.URL_DETAILS_CHECKSUM_MAPPING)
public class UrlDetails {

    @Size(max = 1000, message = "successUrl size must be up to 1000 characters long!")
    private String successUrl;

    @Size(max = 1000, message = "failureUrl size must be up to 1000 characters long!")
    private String failureUrl;

    @Size(max = 1000, message = "pendingUrl size must be up to 1000 characters long!")
    private String pendingUrl;

    @Size(max = 1000, message = "notificationUrl size must be up to 1000 characters long!")
    private String notificationUrl;

    @Size(max = 1000, message = "backUrl size must be up to 1000 characters long!")
    private String backUrl;

    public String getSuccessUrl() {
        return successUrl;
    }

    public void setSuccessUrl(String successUrl) {
        this.successUrl = successUrl;
    }

    public String getFailureUrl() {
        return failureUrl;
    }

    public void setFailureUrl(String failureUrl) {
        this.failureUrl = failureUrl;
    }

    public String getPendingUrl() {
        return pendingUrl;
    }

    public void setPendingUrl(String pendingUrl) {
        this.pendingUrl = pendingUrl;
    }

    public String getNotificationUrl() {
        return notificationUrl;
    }

    public void setNotificationUrl(String notificationUrl) {
        this.notificationUrl = notificationUrl;
    }

    public String getBackUrl() {
        return backUrl;
    }

    public void setBackUrl(String backUrl) {
        this.backUrl = backUrl;
    }
}


text:
            Menu

                Women

                Fashion New

                        Tops Hot!

                                Evening Tops

                                Shirts & Blouses

                                Tunics

                                Vests

                        Dresses Hot!

                                Casual Dresses

                                Evening

                                Designer

                                Party

                        Shoes

                                Flat Shoes

                                Flat Sandals

                                Boots

                                Heels

                        Jewelry

                                Bracelets

                                Necklaces & Pendants

                                Pins & Brooches

                        Lingerie

                                Bras

                                Bodies

                                Lingerie Sets

                                Shapewear

                        Jackets

                                Coats

                                Jackets

                                Leather Jackets

                                Blazers

                        Bags & Purses

                                Bags

                                Designer Handbags

                                Purses

                                Shoulder Bags

                        Swimwear

                                Swimsuits

                                Beach Clothing

                                Bikinis

                Electronics

                        Smartphones

                                Sample New

                                Apple

                                Samsung

                                BlackBerry

                                Motorola

                                Nokia

                                HTC

                        Accessories

                                Headsets

                                Batteries

                                Screen Protectors

                                Memory Cards

                                Cables & Adapters

                                Chargers

                                Cases

                        Cameras

                                Digital Cameras

                                Camcorders

                                Lenses

                                Filters

                                Tripods

                        Computers

                                Laptops

                                Hard Drives

                                Monitors

                                Processors

                Digital

                About Us

            <a class=" level-top" href="<?php echo Yii::app()->homeUrl ?>"><?php echo F::t('Home') ?>

            <a href="<?php echo Yii::app()->createUrl('/catalog/women') ?>" class="level-top">
                <?php echo F::t('Women') ?>

            <a href="<?php echo Yii::app()->createUrl('/catalog/fashion') ?>" class="level-top">
                <?php echo F::t('Fashion') ?> <?php echo F::t('New') ?>

Featured Categories:

                                <?php echo CHtml::link(F::t('Dresses'), array('/catalog/dresses')) ?>

                                <?php echo CHtml::link(F::t('Evening Tops'), array('/catalog/tops')) ?>

                                <?php echo CHtml::link(F::t('Shirts & Blouses'), array('/catalog/shirts-blouses')) ?>

                                Add

                                More

                                Custom

                                Links

                                Tops Hot!

                                        Evening Tops

                                        Shirts & Blouses

                                        Tunics

                                        Vests

                                Dresses Hot!

                                        Casual Dresses

                                        Evening

                                        Designer

                                        Party

                                Shoes

                                        Flat Shoes

                                        Flat Sandals

                                        Boots

                                        Heels

                                Jewelry

                                        Bracelets

                                        Necklaces & Pendants

                                        Pins & Brooches

                                Lingerie

                                        Bras

                                        Bodies

                                        Lingerie Sets

                                        Shapewear

                                Jackets

                                        Coats

                                        Jackets

                                        Leather Jackets

                                        Blazers

                                Bags & Purses

                                        Bags

                                        Designer Handbags

                                        Purses

                                        Shoulder Bags

                                Swimwear

                                        Swimsuits

                                        Beach Clothing

                                        Bikinis

                        <img src="<?php echo F::themeUrl() ?>/media/01.jpg" alt="Sample category" />

Featured Category

This is a custom block ready to display any content. You can add blocks to any category in the catalog...

                        View Category

Custom block:

                                These

                                Are

                                Sample

                                Custom

                                Links

            <a href="<?php echo Yii::app()->createUrl('/catalog/electronics') ?>" class="level-top">
                <?php echo F::t('Electronics') ?>

Recommended Products:

                                Configurable Phone

                                Galaxy S3

                                Galaxy S4

                                iPad Retina

                                iPhone 5

                                <img src="<?php echo F::themeUrl() ?>/media/01.png" alt="Sample image" title="Sample category block, you can replace it with custom content">

                                Smartphones

                                        Sample New

                                        Apple

                                        Samsung

                                        BlackBerry

                                        Motorola

                                        Nokia

                                        HTC

                                <img src="<?php echo F::themeUrl() ?>/media/02.png" alt="Sample image" title="Sample category block, you can replace it with custom content">

                                Accessories

                                        Headsets

                                        Batteries

                                        Screen Protectors

                                        Memory Cards

                                        Cables & Adapters

                                        Chargers

                                        Cases

                                <img src="<?php echo F::themeUrl() ?>/media/03.png" alt="Magento category image" title="Sample category block, you can replace it with custom content">

                                Cameras

                                        Digital Cameras

                                        Camcorders

                                        Lenses

                                        Filters

                                        Tripods

                                <img src="<?php echo F::themeUrl() ?>/media/04.png" alt="Sample image" title="Sample category block, you can replace it with custom content">

                                Computers

                                        Laptops

                                        Hard Drives

                                        Monitors

                                        Processors

                        <img src="<?php echo F::themeUrl() ?>/media/02.jpg" alt="Sample custom content of the category block" />

Featured Category

This is a custom block ready to display any content. You can add blocks to any category in the catalog...

                        View Category

            <a href="<?php echo Yii::app()->createUrl('/site/page', array('view'=>'digital')) ?>" class="level-top">
                <?php echo F::t('Digital') ?>

            Custom

Responsive Magento Theme

Ultimo is a premium Magento theme with advanced admin module. It's extremely customizable and fully responsive. Can be used for every type of store.

Buy this Magento theme

                        <img src="<?php echo F::themeUrl() ?>/media/01(1).png" alt="Magento CMS blocks">

50+ CMS blocks

You can use CMS blocks as content placeholders to display custom content in almost every part of the store. Import sample CMS blocks from the demo.

                            See all features

                        <img src="<?php echo F::themeUrl() ?>/media/02(1).png" alt="Magento theme documentation">

140-pages documentation

The best Magento theme documentation on ThemeForest. It also describes selected Magento features which you need to know when starting to work with Magento.

                            See all features

                        <img src="<?php echo F::themeUrl() ?>/media/03(1).png" alt="Create Magento sub-themes">

Easy to customize

Use Ultimo as a starting point for your custom projects. Unlike many other themes, Ultimo lets you create multiple custom sub-themes (theme variants) for your clients.

                            See all features

            <a class="level-top" href="<?php echo Yii::app()->createUrl('/page/index', array('key'=>'about')) ?>" title="About Us">
                <?php echo F::t('About Us') ?>


text:
// Template Source: BaseEntity.java.tt
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All Rights Reserved.  Licensed under the MIT License.  See License in the project root for license information.
// ------------------------------------------------------------------------------

package com.microsoft.graph.models;
import com.microsoft.graph.serializer.ISerializer;
import com.microsoft.graph.serializer.IJsonBackedObject;
import com.microsoft.graph.serializer.AdditionalDataManager;
import java.util.EnumSet;
import com.microsoft.graph.http.BaseCollectionPage;
import com.microsoft.graph.models.Entity;
import com.microsoft.graph.requests.ManagedEBookCollectionPage;
import com.microsoft.graph.requests.MobileAppCategoryCollectionPage;
import com.microsoft.graph.requests.ManagedDeviceMobileAppConfigurationCollectionPage;
import com.microsoft.graph.requests.MobileAppCollectionPage;
import com.microsoft.graph.requests.VppTokenCollectionPage;
import com.microsoft.graph.requests.AndroidManagedAppProtectionCollectionPage;
import com.microsoft.graph.requests.DefaultManagedAppProtectionCollectionPage;
import com.microsoft.graph.requests.IosManagedAppProtectionCollectionPage;
import com.microsoft.graph.requests.ManagedAppPolicyCollectionPage;
import com.microsoft.graph.requests.ManagedAppRegistrationCollectionPage;
import com.microsoft.graph.requests.ManagedAppStatusCollectionPage;
import com.microsoft.graph.requests.MdmWindowsInformationProtectionPolicyCollectionPage;
import com.microsoft.graph.requests.TargetedManagedAppConfigurationCollectionPage;
import com.microsoft.graph.requests.WindowsInformationProtectionPolicyCollectionPage;

import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;

// **NOTE** This file was generated by a tool and any changes will be overwritten.

/**
 * The class for the Device App Management.
 */
public class DeviceAppManagement extends Entity implements IJsonBackedObject {

    /**
     * The Is Enabled For Microsoft Store For Business.
     * Whether the account is enabled for syncing applications from the Microsoft Store for Business.
     */
    @SerializedName(value = "isEnabledForMicrosoftStoreForBusiness", alternate = {"IsEnabledForMicrosoftStoreForBusiness"})
    @Expose
	@Nullable
    public Boolean isEnabledForMicrosoftStoreForBusiness;

    /**
     * The Microsoft Store For Business Language.
     * The locale information used to sync applications from the Microsoft Store for Business. Cultures that are specific to a country/region. The names of these cultures follow RFC 4646 (Windows Vista and later). The format is -<country/regioncode2>, where  is a lowercase two-letter code derived from ISO 639-1 and <country/regioncode2> is an uppercase two-letter code derived from ISO 3166. For example, en-US for English (United States) is a specific culture.
     */
    @SerializedName(value = "microsoftStoreForBusinessLanguage", alternate = {"MicrosoftStoreForBusinessLanguage"})
    @Expose
	@Nullable
    public String microsoftStoreForBusinessLanguage;

    /**
     * The Microsoft Store For Business Last Completed Application Sync Time.
     * The last time an application sync from the Microsoft Store for Business was completed.
     */
    @SerializedName(value = "microsoftStoreForBusinessLastCompletedApplicationSyncTime", alternate = {"MicrosoftStoreForBusinessLastCompletedApplicationSyncTime"})
    @Expose
	@Nullable
    public java.time.OffsetDateTime microsoftStoreForBusinessLastCompletedApplicationSyncTime;

    /**
     * The Microsoft Store For Business Last Successful Sync Date Time.
     * The last time the apps from the Microsoft Store for Business were synced successfully for the account.
     */
    @SerializedName(value = "microsoftStoreForBusinessLastSuccessfulSyncDateTime", alternate = {"MicrosoftStoreForBusinessLastSuccessfulSyncDateTime"})
    @Expose
	@Nullable
    public java.time.OffsetDateTime microsoftStoreForBusinessLastSuccessfulSyncDateTime;

    /**
     * The Managed EBooks.
     * The Managed eBook.
     */
    @SerializedName(value = "managedEBooks", alternate = {"ManagedEBooks"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.ManagedEBookCollectionPage managedEBooks;

    /**
     * The Mobile App Categories.
     * The mobile app categories.
     */
    @SerializedName(value = "mobileAppCategories", alternate = {"MobileAppCategories"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.MobileAppCategoryCollectionPage mobileAppCategories;

    /**
     * The Mobile App Configurations.
     * The Managed Device Mobile Application Configurations.
     */
    @SerializedName(value = "mobileAppConfigurations", alternate = {"MobileAppConfigurations"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.ManagedDeviceMobileAppConfigurationCollectionPage mobileAppConfigurations;

    /**
     * The Mobile Apps.
     * The mobile apps.
     */
    @SerializedName(value = "mobileApps", alternate = {"MobileApps"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.MobileAppCollectionPage mobileApps;

    /**
     * The Vpp Tokens.
     * List of Vpp tokens for this organization.
     */
    @SerializedName(value = "vppTokens", alternate = {"VppTokens"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.VppTokenCollectionPage vppTokens;

    /**
     * The Android Managed App Protections.
     * Android managed app policies.
     */
    @SerializedName(value = "androidManagedAppProtections", alternate = {"AndroidManagedAppProtections"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.AndroidManagedAppProtectionCollectionPage androidManagedAppProtections;

    /**
     * The Default Managed App Protections.
     * Default managed app policies.
     */
    @SerializedName(value = "defaultManagedAppProtections", alternate = {"DefaultManagedAppProtections"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.DefaultManagedAppProtectionCollectionPage defaultManagedAppProtections;

    /**
     * The Ios Managed App Protections.
     * iOS managed app policies.
     */
    @SerializedName(value = "iosManagedAppProtections", alternate = {"IosManagedAppProtections"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.IosManagedAppProtectionCollectionPage iosManagedAppProtections;

    /**
     * The Managed App Policies.
     * Managed app policies.
     */
    @SerializedName(value = "managedAppPolicies", alternate = {"ManagedAppPolicies"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.ManagedAppPolicyCollectionPage managedAppPolicies;

    /**
     * The Managed App Registrations.
     * The managed app registrations.
     */
    @SerializedName(value = "managedAppRegistrations", alternate = {"ManagedAppRegistrations"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.ManagedAppRegistrationCollectionPage managedAppRegistrations;

    /**
     * The Managed App Statuses.
     * The managed app statuses.
     */
    @SerializedName(value = "managedAppStatuses", alternate = {"ManagedAppStatuses"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.ManagedAppStatusCollectionPage managedAppStatuses;

    /**
     * The Mdm Windows Information Protection Policies.
     * Windows information protection for apps running on devices which are MDM enrolled.
     */
    @SerializedName(value = "mdmWindowsInformationProtectionPolicies", alternate = {"MdmWindowsInformationProtectionPolicies"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.MdmWindowsInformationProtectionPolicyCollectionPage mdmWindowsInformationProtectionPolicies;

    /**
     * The Targeted Managed App Configurations.
     * Targeted managed app configurations.
     */
    @SerializedName(value = "targetedManagedAppConfigurations", alternate = {"TargetedManagedAppConfigurations"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.TargetedManagedAppConfigurationCollectionPage targetedManagedAppConfigurations;

    /**
     * The Windows Information Protection Policies.
     * Windows information protection for apps running on devices which are not MDM enrolled.
     */
    @SerializedName(value = "windowsInformationProtectionPolicies", alternate = {"WindowsInformationProtectionPolicies"})
    @Expose
	@Nullable
    public com.microsoft.graph.requests.WindowsInformationProtectionPolicyCollectionPage windowsInformationProtectionPolicies;

    /**
     * Sets the raw JSON object
     *
     * @param serializer the serializer
     * @param json the JSON object to set this object to
     */
    public void setRawObject(@Nonnull final ISerializer serializer, @Nonnull final JsonObject json) {

        if (json.has("managedEBooks")) {
            managedEBooks = serializer.deserializeObject(json.get("managedEBooks"), com.microsoft.graph.requests.ManagedEBookCollectionPage.class);
        }

        if (json.has("mobileAppCategories")) {
            mobileAppCategories = serializer.deserializeObject(json.get("mobileAppCategories"), com.microsoft.graph.requests.MobileAppCategoryCollectionPage.class);
        }

        if (json.has("mobileAppConfigurations")) {
            mobileAppConfigurations = serializer.deserializeObject(json.get("mobileAppConfigurations"), com.microsoft.graph.requests.ManagedDeviceMobileAppConfigurationCollectionPage.class);
        }

        if (json.has("mobileApps")) {
            mobileApps = serializer.deserializeObject(json.get("mobileApps"), com.microsoft.graph.requests.MobileAppCollectionPage.class);
        }

        if (json.has("vppTokens")) {
            vppTokens = serializer.deserializeObject(json.get("vppTokens"), com.microsoft.graph.requests.VppTokenCollectionPage.class);
        }

        if (json.has("androidManagedAppProtections")) {
            androidManagedAppProtections = serializer.deserializeObject(json.get("androidManagedAppProtections"), com.microsoft.graph.requests.AndroidManagedAppProtectionCollectionPage.class);
        }

        if (json.has("defaultManagedAppProtections")) {
            defaultManagedAppProtections = serializer.deserializeObject(json.get("defaultManagedAppProtections"), com.microsoft.graph.requests.DefaultManagedAppProtectionCollectionPage.class);
        }

        if (json.has("iosManagedAppProtections")) {
            iosManagedAppProtections = serializer.deserializeObject(json.get("iosManagedAppProtections"), com.microsoft.graph.requests.IosManagedAppProtectionCollectionPage.class);
        }

        if (json.has("managedAppPolicies")) {
            managedAppPolicies = serializer.deserializeObject(json.get("managedAppPolicies"), com.microsoft.graph.requests.ManagedAppPolicyCollectionPage.class);
        }

        if (json.has("managedAppRegistrations")) {
            managedAppRegistrations = serializer.deserializeObject(json.get("managedAppRegistrations"), com.microsoft.graph.requests.ManagedAppRegistrationCollectionPage.class);
        }

        if (json.has("managedAppStatuses")) {
            managedAppStatuses = serializer.deserializeObject(json.get("managedAppStatuses"), com.microsoft.graph.requests.ManagedAppStatusCollectionPage.class);
        }

        if (json.has("mdmWindowsInformationProtectionPolicies")) {
            mdmWindowsInformationProtectionPolicies = serializer.deserializeObject(json.get("mdmWindowsInformationProtectionPolicies"), com.microsoft.graph.requests.MdmWindowsInformationProtectionPolicyCollectionPage.class);
        }

        if (json.has("targetedManagedAppConfigurations")) {
            targetedManagedAppConfigurations = serializer.deserializeObject(json.get("targetedManagedAppConfigurations"), com.microsoft.graph.requests.TargetedManagedAppConfigurationCollectionPage.class);
        }

        if (json.has("windowsInformationProtectionPolicies")) {
            windowsInformationProtectionPolicies = serializer.deserializeObject(json.get("windowsInformationProtectionPolicies"), com.microsoft.graph.requests.WindowsInformationProtectionPolicyCollectionPage.class);
        }
    }
}


text:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using OrionLib.Subscribe.SelfHosting;

namespace OrionLib.IntegrationTests
{
    // Warning: these tests are not 100% deterministic because of Orion's chaotic nature. They also can take very long.

    [Timeout(10000)]
    public class OrionSubscriptionTests
    {
        class Fixture
        {
            private readonly IOrion _sut;
            private readonly BlockingCollection<IEnumerable<OrionEntity>> _orionEvents;

            public Fixture()
            {
                var config = TestConfiguration.GetOrionConfiguration();

                _sut = new OrionFactory().Create(config);
                _orionEvents = new BlockingCollection<IEnumerable<OrionEntity>>();
            }

            public async Task CreateEntityAsync(OrionEntity orionEntity)
            {
                await _sut.CreateOrUpdateEntityAsync(orionEntity);
            }

            public ISelfHostedOrionSubscription StartSubscription(string type, string[] attributes)
            {
                var subscription = _sut.CreateSelfHostedSubscription(TestConfiguration.SubscriptionAddress, TestConfiguration.SubscriptionAddress, type, attributes)
                    .WithSubscriptionTiming(duration: TimeSpan.FromSeconds(3), renewingTimeout: TimeSpan.FromSeconds(2))
                    .OnEntityChanged(_orionEvents.Add)
                    .Create();

                subscription.Start();

                return subscription;
            }

            public void WaitForSubscriptionToExpire()
            {
                Thread.Sleep(TimeSpan.FromSeconds(4));
            }

            public async Task UpdateAttributeAsync(string type, string id, string attribute, string newValue)
            {
                await _sut.UpdateAttributeAsync(type, id, attribute, newValue);
            }

            public void WaitUntilAttributeChangesTo(string expectedType, string expectedId, string expectedAttribute, string expectedValue)
            {
                while (true)
                {
                    var entities = _orionEvents.Take();

                    if (ExpectedChange(entities, expectedType, expectedId, expectedAttribute, expectedValue))
                    {
                        return;
                    }
                }
            }

            private static bool ExpectedChange(IEnumerable<OrionEntity> entities, string type, string id, string attribute, string newValue)
            {
                var entity = entities.FirstOrDefault();

                return entity != null
                    && entity.Type == type
                    && entity.Id == id
                    && entity.GetAttributeValueByName(attribute) == newValue;
            }
        }

        [Test]
        public async Task Can_Subscribe_To_Entity_Attribute_Changes()
        {
            var fixture = new Fixture();

            await fixture.CreateEntityAsync(new OrionEntity("book", "book_1", new[]
            {
                new OrionAttribute("title", "string", "Solaris")
            }));

            using (fixture.StartSubscription("book", new[] { "title" }))
            {
                await fixture.UpdateAttributeAsync("book", "book_1", "title", "Fiasco");

                fixture.WaitUntilAttributeChangesTo(
                    expectedType: "book",
                    expectedId: "book_1",
                    expectedAttribute: "title",
                    expectedValue: "Fiasco");
            }

            Assert.Pass("Update notification was successfully received.");
        }

        [Test]
        public async Task Can_Update_Subscription_When_It_Expires()
        {
            var fixture = new Fixture();

            await fixture.CreateEntityAsync(new OrionEntity("book", "book_1", new[]
            {
                new OrionAttribute("title", "string", "Solaris")
            }));

            using (fixture.StartSubscription("book", new[] { "title" }))
            {
                fixture.WaitForSubscriptionToExpire();

                await fixture.UpdateAttributeAsync("book", "book_1", "title", "Fiasco");

                fixture.WaitUntilAttributeChangesTo(
                    expectedType: "book",
                    expectedId: "book_1",
                    expectedAttribute: "title",
                    expectedValue: "Fiasco");
            }

            Assert.Pass("Subscription was successfully renewed and notification was received.");
        }
    }
}


text:
package org.vaadin.leif.persona;

public class PersonaErrorEvent extends PersonaEvent {

    private final String message;
    private final Throwable cause;

    public PersonaErrorEvent(Persona source, String message) {
        this(source, null, message);
    }

    public PersonaErrorEvent(Persona source, Throwable cause) {
        this(source, cause, cause.getLocalizedMessage());
    }

    public PersonaErrorEvent(Persona source, Throwable cause, String message) {
        super(source);
        this.cause = cause;
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public Throwable getCause() {
        return cause;
    }

}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Untitled Document: Core Files</title>

<meta name="description" content="Untitled Document: Core Files">
<meta name="keywords" content="Untitled Document: Core Files">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="BFD-Index.html#BFD-Index" rel="index" title="BFD Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="BFD-front-end.html#BFD-front-end" rel="up" title="BFD front end">
<link href="Targets.html#Targets" rel="next" title="Targets">
<link href="howto-manager.html#howto-manager" rel="prev" title="howto manager">

Next: Targets, Previous: Relocations, Up: BFD front end   [Contents][Index]

2.11 Core files

2.11.1 Core file functions

Description

These are functions pertaining to core files.

2.11.1.1 bfd_core_file_failing_command

Synopsis

const char *bfd_core_file_failing_command (bfd *abfd);

Description

Return a read-only string explaining which program was running
when it failed and produced the core file <var>abfd</var>.

2.11.1.2 bfd_core_file_failing_signal

Synopsis

int bfd_core_file_failing_signal (bfd *abfd);

Description

Returns the signal number which caused the core dump which
generated the file the BFD <var>abfd</var> is attached to.

2.11.1.3 bfd_core_file_pid

Synopsis

int bfd_core_file_pid (bfd *abfd);

Description

Returns the PID of the process the core dump the BFD
<var>abfd</var> is attached to was generated from.

2.11.1.4 core_file_matches_executable_p

Synopsis

bfd_boolean core_file_matches_executable_p
   (bfd *core_bfd, bfd *exec_bfd);

Description

Return TRUE if the core file attached to <var>core_bfd</var>
was generated by a run of the executable file attached to
<var>exec_bfd</var>, FALSE otherwise.

2.11.1.5 generic_core_file_matches_executable_p

Synopsis

bfd_boolean generic_core_file_matches_executable_p
   (bfd *core_bfd, bfd *exec_bfd);

Description

Return TRUE if the core file attached to <var>core_bfd</var>
was generated by a run of the executable file attached
to <var>exec_bfd</var>.  The match is based on executable
basenames only.

Note: When not able to determine the core file failing
command or the executable name, we still return TRUE even
though we’re not sure that core file and executable match.
This is to avoid generating a false warning in situations
where we really don’t know whether they match or not.

Next: Targets, Previous: Relocations, Up: BFD front end   [Contents][Index]


text:
<form name="myForm">

    Name
    <input type="text" name="name" ng-model="project.name" required>

        Required

    Website
    <input type="url" name="site" ng-model="project.site" required>

        Required

        Not a URL

  Description
  <textarea name="description" ng-model="project.description"></textarea>

  Cancel
  <button ng-click="save()" ng-disabled="isClean() || myForm.$invalid"
          class="btn btn-primary">Save</button>
  <button ng-click="destroy()"
          ng-show="project.$id" class="btn btn-danger">Delete</button>
</form>


text:
package data;

public class ConstraintMeta extends EntityMeta{
	public String expression;
	public String target_id;
	public String name;
}


text:
GENCONF_DIR = 'genconf'
CONFIG_PATH = GENCONF_DIR + '/config.yaml'
SSH_KEY_PATH = GENCONF_DIR + '/ssh_key'
IP_DETECT_PATH = GENCONF_DIR + '/ip-detect'
CLUSTER_PACKAGES_PATH = GENCONF_DIR + '/cluster_packages.json'
SERVE_DIR = GENCONF_DIR + '/serve'
STATE_DIR = GENCONF_DIR + '/state'
BOOTSTRAP_DIR = SERVE_DIR + '/bootstrap'
ARTIFACT_DIR = 'artifacts'


text:
package org.apache.pig.test.pigmix.mapreduce;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.jobcontrol.Job;
import org.apache.hadoop.mapred.jobcontrol.JobControl;

public class L2 {

    public static class Join extends MapReduceBase
        implements Mapper<LongWritable, Text, Text, Text> {

        Set<String> hash;

        public void configure(JobConf conf) {
            try {
                Path[] paths = DistributedCache.getLocalCacheFiles(conf);
                if (paths == null || paths.length < 1) {
                    throw new RuntimeException("DistributedCache no work.");
                }

                // Open the small table
                BufferedReader reader =
                    new BufferedReader(new InputStreamReader(new
                    FileInputStream(paths[0].toString())));
                String line;
                hash = new HashSet<String>(500);
                while ((line = reader.readLine()) != null) {
                    if (line.length() < 1) continue;
                    String[] fields = line.split("");
                    hash.add(fields[0]);
                }
                reader.close();
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }
        }

        public void map(
                LongWritable k,
                Text val,
                OutputCollector<Text, Text> oc,
                Reporter reporter) throws IOException {

            List<Text> fields = Library.splitLine(val, '');
            String name = fields.get(0).toString();

            if (hash.contains(name)) {
                StringBuffer sb = new StringBuffer();
                sb.append(name);
                sb.append("");
                sb.append(fields.get(6).toString());
                oc.collect(null, new Text(sb.toString()));
            }

        }
    }

    public static void main(String[] args) throws IOException, URISyntaxException {

        if (args.length!=3) {
            System.out.println("Parameters: inputDir outputDir parallel");
            System.exit(1);
        }
        String inputDir = args[0];
        String outputDir = args[1];
        JobConf lp = new JobConf(L2.class);
        lp.setJobName("L2 Load Page Views");
        lp.setInputFormat(TextInputFormat.class);
        lp.setOutputKeyClass(Text.class);
        lp.setOutputValueClass(Text.class);
        lp.setMapperClass(Join.class);
        Properties props = System.getProperties();
        for (Map.Entry<Object,Object> entry : props.entrySet()) {
            lp.set((String)entry.getKey(), (String)entry.getValue());
        }
        DistributedCache.addCacheFile(new URI(inputDir + "/power_users"), lp);
        FileInputFormat.addInputPath(lp, new Path(inputDir + "/page_views"));
        FileOutputFormat.setOutputPath(lp, new Path(outputDir + "/L2out"));
        lp.setNumReduceTasks(0);
        Job loadPages = new Job(lp);

        JobControl jc = new JobControl("L2 join");
        jc.addJob(loadPages);

        new Thread(jc).start();

        int i = 0;
        while(!jc.allFinished()){
            ArrayList<Job> failures = jc.getFailedJobs();
            if (failures != null && failures.size() > 0) {
                for (Job failure : failures) {
                    System.err.println(failure.getMessage());
                }
                break;
            }

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {}

            if (i % 10000 == 0) {
                System.out.println("Running jobs");
                ArrayList<Job> running = jc.getRunningJobs();
                if (running != null && running.size() > 0) {
                    for (Job r : running) {
                        System.out.println(r.getJobName());
                    }
                }
                System.out.println("Ready jobs");
                ArrayList<Job> ready = jc.getReadyJobs();
                if (ready != null && ready.size() > 0) {
                    for (Job r : ready) {
                        System.out.println(r.getJobName());
                    }
                }
                System.out.println("Waiting jobs");
                ArrayList<Job> waiting = jc.getWaitingJobs();
                if (waiting != null && waiting.size() > 0) {
                    for (Job r : ready) {
                        System.out.println(r.getJobName());
                    }
                }
                System.out.println("Successful jobs");
                ArrayList<Job> success = jc.getSuccessfulJobs();
                if (success != null && success.size() > 0) {
                    for (Job r : ready) {
                        System.out.println(r.getJobName());
                    }
                }
            }
            i++;
        }
        ArrayList<Job> failures = jc.getFailedJobs();
        if (failures != null && failures.size() > 0) {
            for (Job failure : failures) {
                System.err.println(failure.getMessage());
            }
        }
        jc.stop();
    }

}


text:
<%namespace name='static' file='/static_content.html'/>
<link rel="stylesheet" href="${static.url('themes/testsnc/css/vendor/sen-identity.css')}" />
<link rel="stylesheet" href="${static.url('themes/testsnc/css/vendor/devSenCSS.css')}" />
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,900,300italic,400italic,700italic,900italic,' rel='stylesheet' type='text/css'>
<!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <script type="text/javascript">
    $(document).ready(function () {
      alert("Warning: you are using an unsupported browser\nand may be unable to use some features.\n\nWe suggest you use either Mozilla Firefox or\nGoogle Chrome.");
    });
  </script>
<![endif]-->
<!--[if IE 8]>
  <link rel="stylesheet" type="text/css" href="${static.url('themes/testsnc/css/vendor/ie8.css')}" />
<![endif]-->
<!--[if IE 7]>
  <link rel="stylesheet" type="text/css" href="${static.url('themes/testsnc/css/vendor/ie7.css')}" />
<![endif]-->