<commit_before>/*
OstreeDeploy Action

Deploy the OSTree branch to the image.
If any preparation has been done for rootfs, it can be overwritten
during this step.

Action 'image-partition' must be called prior to OSTree deploy.

Yaml syntax:
 - action: ostree-deploy
   repository: repository name
   remote_repository: URL
   branch: branch name
   os: os name
   setup-fstab: bool
   setup-kernel-cmdline: bool
   appendkernelcmdline: arguments

Mandatory properties:

- remote_repository -- URL to remote OSTree repository for pulling stateroot branch.
Currently not implemented, please prepare local repository instead.

- repository -- path to repository with OSTree structure.
This path is relative to 'artifact' directory.

- os -- os deployment name, as explained in:
https://ostree.readthedocs.io/en/latest/manual/deployment/

- branch -- branch of the repository to use for populating the image.

Optional properties:

- setup-fstab -- create '/etc/fstab' file for image

- setup-kernel-cmdline -- add the information from the 'image-partition'
action to the configured commandline.

- append-kernel-cmdline -- additional kernel command line arguments passed to kernel.
*/
package actions

import (
	"fmt"
	"io"
	"os"
	"path"
	"strings"

	"github.com/go-debos/debos"
	ostree "github.com/sjoerdsimons/ostree-go/pkg/otbuiltin"
)

type OstreeDeployAction struct {
	debos.BaseAction    `yaml:",inline"`
	Repository          string
	RemoteRepository    string "remote_repository"
	Branch              string
	Os                  string
	SetupFSTab          bool   `yaml:"setup-fstab"`
	SetupKernelCmdline  bool   `yaml:"setup-kernel-cmdline"`
	AppendKernelCmdline string `yaml:"append-kernel-cmdline"`
}

func NewOstreeDeployAction() *OstreeDeployAction {
	ot := &OstreeDeployAction{SetupFSTab: true, SetupKernelCmdline: true}
	ot.Description = "Deploying from ostree"
	return ot
}

func (ot *OstreeDeployAction) setupFSTab(deployment *ostree.Deployment, context *debos.DebosContext) error {
	deploymentDir := fmt.Sprintf("ostree/deploy/%s/deploy/%s.%d",
		deployment.Osname(), deployment.Csum(), deployment.Deployserial())

	etcDir := path.Join(context.Rootdir, deploymentDir, "etc")

	err := os.Mkdir(etcDir, 0755)
	if err != nil && !os.IsExist(err) {
		return err
	}

	dst, err := os.OpenFile(path.Join(etcDir, "fstab"), os.O_WRONLY|os.O_CREATE, 0755)
	defer dst.Close()
	if err != nil {
		return err
	}

	_, err = io.Copy(dst, &context.ImageFSTab)

	return err
}

func (ot *OstreeDeployAction) Run(context *debos.DebosContext) error {
	ot.LogStart()

	// This is to handle cases there we didn't partition an image
	if len(context.ImageMntDir) != 0 {
		/* First deploy the current rootdir to the image so it can seed e.g.
		 * bootloader configuration */
		err := debos.Command{}.Run("Deploy to image", "cp", "-a", context.Rootdir+"/.", context.ImageMntDir)
		if err != nil {
			return fmt.Errorf("rootfs deploy failed: %v", err)
		}
		context.Rootdir = context.ImageMntDir
	}

	repoPath := "file://" + path.Join(context.Artifactdir, ot.Repository)

	sysroot := ostree.NewSysroot(context.Rootdir)
	err := sysroot.InitializeFS()
	if err != nil {
		return err
	}

	err = sysroot.InitOsname(ot.Os, nil)
	if err != nil {
		return err
	}

	/* HACK: Getting the repository form the sysroot gets ostree confused on
	 * whether it should configure /etc/ostree or the repo configuration,
	   so reopen by hand */
	/* dstRepo, err := sysroot.Repo(nil) */
	dstRepo, err := ostree.OpenRepo(path.Join(context.Rootdir, "ostree/repo"))
	if err != nil {
		return err
	}

	/* FIXME: add support for gpg signing commits so this is no longer needed */
	opts := ostree.RemoteOptions{NoGpgVerify: true}
	err = dstRepo.RemoteAdd("origin", ot.RemoteRepository, opts, nil)
	if err != nil {
		return err
	}

	var options ostree.PullOptions
	options.OverrideRemoteName = "origin"
	options.Refs = []string{ot.Branch}

	err = dstRepo.PullWithOptions(repoPath, options, nil, nil)
	if err != nil {
		return err
	}

	/* Required by ostree to make sure a bunch of information was pulled in  */
	sysroot.Load(nil)

	revision, err := dstRepo.ResolveRev(ot.Branch, false)
	if err != nil {
		return err
	}

	var kargs []string
	if ot.SetupKernelCmdline {
		kargs = append(kargs, context.ImageKernelRoot)
	}

	if ot.AppendKernelCmdline != "" {
		s := strings.Split(ot.AppendKernelCmdline, " ")
		kargs = append(kargs, s...)
	}

	origin := sysroot.OriginNewFromRefspec("origin:" + ot.Branch)
	deployment, err := sysroot.DeployTree(ot.Os, revision, origin, nil, kargs, nil)
	if err != nil {
		return err
	}

	if ot.SetupFSTab {
		err = ot.setupFSTab(deployment, context)
		if err != nil {
			return err
		}
	}

	err = sysroot.SimpleWriteDeployment(ot.Os, deployment, nil, 0, nil)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>action: ostree-deploy: fix 'filesystem' origin<commit_after>/*
OstreeDeploy Action

Deploy the OSTree branch to the image.
If any preparation has been done for rootfs, it can be overwritten
during this step.

Action 'image-partition' must be called prior to OSTree deploy.

Yaml syntax:
 - action: ostree-deploy
   repository: repository name
   remote_repository: URL
   branch: branch name
   os: os name
   setup-fstab: bool
   setup-kernel-cmdline: bool
   appendkernelcmdline: arguments

Mandatory properties:

- remote_repository -- URL to remote OSTree repository for pulling stateroot branch.
Currently not implemented, please prepare local repository instead.

- repository -- path to repository with OSTree structure.
This path is relative to 'artifact' directory.

- os -- os deployment name, as explained in:
https://ostree.readthedocs.io/en/latest/manual/deployment/

- branch -- branch of the repository to use for populating the image.

Optional properties:

- setup-fstab -- create '/etc/fstab' file for image

- setup-kernel-cmdline -- add the information from the 'image-partition'
action to the configured commandline.

- append-kernel-cmdline -- additional kernel command line arguments passed to kernel.
*/
package actions

import (
	"fmt"
	"io"
	"os"
	"path"
	"strings"

	"github.com/go-debos/debos"
	ostree "github.com/sjoerdsimons/ostree-go/pkg/otbuiltin"
)

type OstreeDeployAction struct {
	debos.BaseAction    `yaml:",inline"`
	Repository          string
	RemoteRepository    string "remote_repository"
	Branch              string
	Os                  string
	SetupFSTab          bool   `yaml:"setup-fstab"`
	SetupKernelCmdline  bool   `yaml:"setup-kernel-cmdline"`
	AppendKernelCmdline string `yaml:"append-kernel-cmdline"`
}

func NewOstreeDeployAction() *OstreeDeployAction {
	ot := &OstreeDeployAction{SetupFSTab: true, SetupKernelCmdline: true}
	ot.Description = "Deploying from ostree"
	return ot
}

func (ot *OstreeDeployAction) setupFSTab(deployment *ostree.Deployment, context *debos.DebosContext) error {
	deploymentDir := fmt.Sprintf("ostree/deploy/%s/deploy/%s.%d",
		deployment.Osname(), deployment.Csum(), deployment.Deployserial())

	etcDir := path.Join(context.Rootdir, deploymentDir, "etc")

	err := os.Mkdir(etcDir, 0755)
	if err != nil && !os.IsExist(err) {
		return err
	}

	dst, err := os.OpenFile(path.Join(etcDir, "fstab"), os.O_WRONLY|os.O_CREATE, 0755)
	defer dst.Close()
	if err != nil {
		return err
	}

	_, err = io.Copy(dst, &context.ImageFSTab)

	return err
}

func (ot *OstreeDeployAction) Run(context *debos.DebosContext) error {
	ot.LogStart()

	// This is to handle cases there we didn't partition an image
	if len(context.ImageMntDir) != 0 {
		/* First deploy the current rootdir to the image so it can seed e.g.
		 * bootloader configuration */
		err := debos.Command{}.Run("Deploy to image", "cp", "-a", context.Rootdir+"/.", context.ImageMntDir)
		if err != nil {
			return fmt.Errorf("rootfs deploy failed: %v", err)
		}
		context.Rootdir = context.ImageMntDir
		context.Origins["filesystem"] = context.ImageMntDir
	}

	repoPath := "file://" + path.Join(context.Artifactdir, ot.Repository)

	sysroot := ostree.NewSysroot(context.Rootdir)
	err := sysroot.InitializeFS()
	if err != nil {
		return err
	}

	err = sysroot.InitOsname(ot.Os, nil)
	if err != nil {
		return err
	}

	/* HACK: Getting the repository form the sysroot gets ostree confused on
	 * whether it should configure /etc/ostree or the repo configuration,
	   so reopen by hand */
	/* dstRepo, err := sysroot.Repo(nil) */
	dstRepo, err := ostree.OpenRepo(path.Join(context.Rootdir, "ostree/repo"))
	if err != nil {
		return err
	}

	/* FIXME: add support for gpg signing commits so this is no longer needed */
	opts := ostree.RemoteOptions{NoGpgVerify: true}
	err = dstRepo.RemoteAdd("origin", ot.RemoteRepository, opts, nil)
	if err != nil {
		return err
	}

	var options ostree.PullOptions
	options.OverrideRemoteName = "origin"
	options.Refs = []string{ot.Branch}

	err = dstRepo.PullWithOptions(repoPath, options, nil, nil)
	if err != nil {
		return err
	}

	/* Required by ostree to make sure a bunch of information was pulled in  */
	sysroot.Load(nil)

	revision, err := dstRepo.ResolveRev(ot.Branch, false)
	if err != nil {
		return err
	}

	var kargs []string
	if ot.SetupKernelCmdline {
		kargs = append(kargs, context.ImageKernelRoot)
	}

	if ot.AppendKernelCmdline != "" {
		s := strings.Split(ot.AppendKernelCmdline, " ")
		kargs = append(kargs, s...)
	}

	origin := sysroot.OriginNewFromRefspec("origin:" + ot.Branch)
	deployment, err := sysroot.DeployTree(ot.Os, revision, origin, nil, kargs, nil)
	if err != nil {
		return err
	}

	if ot.SetupFSTab {
		err = ot.setupFSTab(deployment, context)
		if err != nil {
			return err
		}
	}

	err = sysroot.SimpleWriteDeployment(ot.Os, deployment, nil, 0, nil)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package quic

import (
	"reflect"
	"testing"
)

func TestStreamFrameFrame(t *testing.T) {
	// fin: true, streamID: 1, offset: 1, dataLength: 1
	//data := []byte{0xe4, 0x01, 0x00, 0x01, 0x00, 0x05}
	data := [][]byte{
		// fin: true, streamID: 1, offset: 1, dataLength: 1
		[]byte{0xe4, 0x01, 0x00, 0x01, 0x00, 0x05},
		// fin: false, streamID: 256, offset 0, dataLength: 1
		[]byte{0xa1, 0x01, 0x00, 0x00, 0x05},
	}

	testD := []byte("aiueo")
	fp := NewFramePacket(0, 0)
	actualFrames := []*StreamFrame{
		NewStreamFrame(true, 1, 1, testD),
		NewStreamFrame(false, 256, 0, testD),
	}
	for i, d := range data {
		d := append(d, testD...)
		frame := &StreamFrame{FramePacket: fp}
		actualFrame := actualFrames[i]
		actualFrame.SetPacket(fp)

		actualLen, _ := frame.Parse(d)
		if actualLen != len(d) {
			t.Errorf("got %v\nwant %v", actualLen, len(d))
		}

		if !reflect.DeepEqual(actualFrame, frame) {
			t.Errorf("got %v\nwant %v", actualFrame, frame)
		}

		actualWire, _ := frame.GetWire()
		if !reflect.DeepEqual(actualWire, d) {
			t.Errorf("got %v\nwant %v", actualWire, d)
		}

	}
}

func TestPaddingFrame(t *testing.T) {
	data := []byte{0x00, 0x00, 0x00, 0x00, 0x00}
	fp := NewFramePacket(0, 0)
	fp.DataSize = 1945
	fp.RestSize = 5
	frame := &PaddingFrame{FramePacket: fp}
	actualFrame := NewPaddingFrame()
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestRstStreamFrame(t *testing.T) {
	// streamID:1, offset:1, errorcode: NO_ERROR
	data := []byte{0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}
	fp := NewFramePacket(0, 0)
	frame := &RstStreamFrame{FramePacket: fp}
	actualFrame := NewRstStreamFrame(1, 1, NO_ERROR)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestPingFrame(t *testing.T) {
	data := []byte{0x07}
	fp := NewFramePacket(0, 0)
	frame := &PingFrame{FramePacket: fp}
	actualFrame := NewPingFrame()
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestConnectionCloseFrame(t *testing.T) {
	// errorcode: NO_ERROR, reason length: 14, reason: "This is reason",
	data := []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e}
	reason := "This is reason"
	data = append(data, []byte(reason)...)
	fp := NewFramePacket(0, 0)
	frame := &ConnectionCloseFrame{FramePacket: fp}
	actualFrame := NewConnectionCloseFrame(NO_ERROR, reason)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestGoAwayFrame(t *testing.T) {
	// errorcode: NO_ERROR, last streamID: 1, reason length: 14, reason: "This is reason",
	data := []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0e}
	reason := "This is reason"
	data = append(data, []byte(reason)...)
	fp := NewFramePacket(0, 0)
	frame := &GoAwayFrame{FramePacket: fp}
	actualFrame := NewGoAwayFrame(NO_ERROR, 1, reason)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestWindowUpdateFrame(t *testing.T) {
	// streamID: 1, offset 1
	data := []byte{0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
	fp := NewFramePacket(0, 0)
	frame := &WindowUpdateFrame{FramePacket: fp}
	actualFrame := NewWindowUpdateFrame(1, 1)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestBlockedFrame(t *testing.T) {
	// streamID: 1
	data := []byte{0x05, 0x00, 0x00, 0x00, 0x01}
	fp := NewFramePacket(0, 0)
	frame := &BlockedFrame{FramePacket: fp}
	actualFrame := NewBlockedFrame(1)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestStopWaitingFrame(t *testing.T) {
	// Sent Entropy: 1, least unacked delta: 1
	data := []byte{0x06, 0x01, 0x01}
	fp := NewFramePacket(0, 0)
	frame := &StopWaitingFrame{FramePacket: fp}
	actualFrame := NewStopWaitingFrame(1, 1)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}
<commit_msg>added test case<commit_after>package quic

import (
	"reflect"
	"testing"
)

func TestStreamFrameFrame(t *testing.T) {
	// fin: true, streamID: 1, offset: 1, dataLength: 1
	//data := []byte{0xe4, 0x01, 0x00, 0x01, 0x00, 0x05}
	data := [][]byte{
		// fin: true, streamID: 1, offset: 1, dataLength: 1
		[]byte{0xe4, 0x01, 0x00, 0x01, 0x00, 0x05},
		// fin: false, streamID: 256, offset 0, dataLength: 1
		[]byte{0xa1, 0x01, 0x00, 0x00, 0x05},
	}

	testD := []byte("aiueo")
	fp := NewFramePacket(0, 0)
	actualFrames := []*StreamFrame{
		NewStreamFrame(true, 1, 1, testD),
		NewStreamFrame(false, 256, 0, testD),
	}
	for i, d := range data {
		d := append(d, testD...)
		frame := &StreamFrame{FramePacket: fp}
		actualFrame := actualFrames[i]
		actualFrame.SetPacket(fp)

		actualLen, _ := frame.Parse(d)
		if actualLen != len(d) {
			t.Errorf("got %v\nwant %v", actualLen, len(d))
		}

		if !reflect.DeepEqual(actualFrame, frame) {
			t.Errorf("got %v\nwant %v", actualFrame, frame)
		}

		actualWire, _ := frame.GetWire()
		if !reflect.DeepEqual(actualWire, d) {
			t.Errorf("got %v\nwant %v", actualWire, d)
		}

	}
}

func TestPaddingFrame(t *testing.T) {
	data := []byte{0x00, 0x00, 0x00, 0x00, 0x00}
	fp := NewFramePacket(0, 0)
	fp.DataSize = 1945
	fp.RestSize = 5
	frame := &PaddingFrame{FramePacket: fp}
	actualFrame := NewPaddingFrame()
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestRstStreamFrame(t *testing.T) {
	// streamID:1, offset:1, errorcode: NO_ERROR
	data := []byte{0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}
	fp := NewFramePacket(0, 0)
	frame := &RstStreamFrame{FramePacket: fp}
	actualFrame := NewRstStreamFrame(1, 1, NO_ERROR)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestPingFrame(t *testing.T) {
	data := []byte{0x07}
	fp := NewFramePacket(0, 0)
	frame := &PingFrame{FramePacket: fp}
	actualFrame := NewPingFrame()
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}
}

func TestConnectionCloseFrame(t *testing.T) {
	// errorcode: NO_ERROR, reason length: 14, reason: "This is reason",
	data := []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e}
	reason := "This is reason"
	data = append(data, []byte(reason)...)
	fp := NewFramePacket(0, 0)
	frame := &ConnectionCloseFrame{FramePacket: fp}
	actualFrame := NewConnectionCloseFrame(NO_ERROR, reason)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestGoAwayFrame(t *testing.T) {
	// errorcode: NO_ERROR, last streamID: 1, reason length: 14, reason: "This is reason",
	data := []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0e}
	reason := "This is reason"
	data = append(data, []byte(reason)...)
	fp := NewFramePacket(0, 0)
	frame := &GoAwayFrame{FramePacket: fp}
	actualFrame := NewGoAwayFrame(NO_ERROR, 1, reason)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestWindowUpdateFrame(t *testing.T) {
	// streamID: 1, offset 1
	data := []byte{0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
	fp := NewFramePacket(0, 0)
	frame := &WindowUpdateFrame{FramePacket: fp}
	actualFrame := NewWindowUpdateFrame(1, 1)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestBlockedFrame(t *testing.T) {
	// streamID: 1
	data := []byte{0x05, 0x00, 0x00, 0x00, 0x01}
	fp := NewFramePacket(0, 0)
	frame := &BlockedFrame{FramePacket: fp}
	actualFrame := NewBlockedFrame(1)
	actualFrame.SetPacket(fp)

	actualLen, _ := frame.Parse(data)
	if actualLen != len(data) {
		t.Errorf("got %v\nwant %v", actualLen, len(data))
	}

	if !reflect.DeepEqual(actualFrame, frame) {
		t.Errorf("got %v\nwant %v", actualFrame, frame)
	}

	actualWire, _ := frame.GetWire()
	if !reflect.DeepEqual(actualWire, data) {
		t.Errorf("got %v\nwant %v", actualWire, data)
	}

}

func TestStopWaitingFrame(t *testing.T) {
	data := [][]byte{
		// Sent Entropy: 1, least unacked delta: 1
		[]byte{0x06, 0x01, 0x01},
		// Sent Entropy: 0, least unacked delta: 257
		[]byte{0x06, 0x00, 0x01, 0x01},
	}
	fp := NewFramePacket(0, 0)
	actualFrames := []*StopWaitingFrame{
		NewStopWaitingFrame(1, 1),
		NewStopWaitingFrame(0, 257),
	}

	for i, d := range data {
		if i == 1 {
			fp.PacketHeader.PublicFlags |= SEQUENCE_NUMBER_LENGTH_2
		}
		frame := &StopWaitingFrame{FramePacket: fp}
		actualFrame := actualFrames[i]
		actualFrame.SetPacket(fp)

		actualLen, _ := frame.Parse(d)
		if actualLen != len(d) {
			t.Errorf("got %v\nwant %v", actualLen, len(data))
		}

		if !reflect.DeepEqual(actualFrame, frame) {
			t.Errorf("got %v\nwant %v", actualFrame, frame)
		}

		actualWire, _ := frame.GetWire()
		if !reflect.DeepEqual(actualWire, d) {
			t.Errorf("got %v\nwant %v", actualWire, d)
		}
	}

}
<|endoftext|>


<commit_before>package handler

import (
	"fmt"
	modelServer "github.com/vladpereskokov/Technopark_HighLoad-nginx/src/models/server"
	"net"
)

type Handler struct {
	Connection net.Conn
	Request    *modelServer.Request
	Response   *modelServer.Response
	Dir        string
}

func CreateHandler(dir string) (handlerFunc HandlerFunc) {
	handler := Handler{}
	handler.create(dir)

	return func(channel chan net.Conn) {
		go handler.handle(channel)
	}
}

func (handler *Handler) create(dir string) {
	handler.Request = new(modelServer.Request)

	handler.Response = new(modelServer.Response)
	handler.Response.Status = new(modelServer.Status)
	handler.Response.Headers = make(map[string]string)

	handler.Dir = dir
}

func (handler *Handler) handle(channel chan net.Conn) {
	for {
		conn := <-channel
		buf := make([]byte, 1024)

		_, err := conn.Read(buf)
		if err != nil {
			fmt.Println("Error reading:", err.Error())
		}

		conn.Write([]byte("Message received."))
		conn.Close()
	}
}
<commit_msg>change start servers handler<commit_after>package handler

import (
	"fmt"
	modelServer "github.com/vladpereskokov/Technopark_HighLoad-nginx/src/models/server"
	"net"
)

type Handler struct {
	Connection net.Conn
	Request    *modelServer.Request
	Response   *modelServer.Response
	Dir        string
}

func CreateHandler(dir string) (handlerFunc HandlerFunc) {
	handler := Handler{}
	handler.create(dir)

	return func(channel chan net.Conn) {
		go handler.start(channel)
	}
}

func (handler *Handler) create(dir string) {
	handler.Request = new(modelServer.Request)

	handler.Response = new(modelServer.Response)
	handler.Response.Status = new(modelServer.Status)
	handler.Response.Headers = make(map[string]string)

	handler.Dir = dir
}

func (handler *Handler) start(channel chan net.Conn) {
	for {
		handler.handle(<-channel)
	}
}

func (handler *Handler) handle(connection net.Conn) {
	for {
		buf := make([]byte, 1024)

		_, err := connection.Read(buf)
		if err != nil {
			fmt.Println("Error reading:", err.Error())
		}

		connection.Write([]byte("Message received."))
		connection.Close()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"

	// "database/sql"

	_ "github.com/lib/pq"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":5432", "puerto local para escuchar")
	dbHostname    = flag.String("h", "localhost", "hostname del servidor PostgreSQL")
	dbPort        = flag.String("r", "5432", "puerto del servidor PostgreSQL")
	dbName        = flag.String("d", "dbname", "nombre de la base de datos")
	dbUsername    = flag.String("u", "username", "usuario para acceder al servidor PostgreSQL")
	dbPassword    = flag.String("p", "password", "password para acceder al servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	// messages      = []string{}
)

type msgStruct struct {
	Type    string
	Content string
}

var (
	db *sql.DB
)

func main() {
	flag.Parse()
	// dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
	// 	*dbUsername, *dbPassword, *dbName)
	// db, err := sql.Open("postgres", dbinfo)

	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	msgOut := make(chan msgStruct)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			inFile, _ := os.Open("canales_list.txt")
			defer inFile.Close()
			scanner := bufio.NewScanner(inFile)
			scanner.Split(bufio.ScanLines)

			for scanner.Scan() {
				time.Sleep(time.Second * 1)
				// messages = []string{}
				// fmt.Println(scanner.Text())
				// msgOut <- fmt.Sprintf("# %s\n", scanner.Text())
				msgOut <- msgStruct{Type: "C", Content: scanner.Text()}
				_, _, errs := gorequest.New().Get(fmt.Sprintf("%s%s", *remoteService, scanner.Text())).End()
				if errs != nil {
					log.Fatalf("log failed: %v", errs)
				}
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		f, err := os.OpenFile("/all.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		for msg := range msgs {
			// fmt.Println(msg)
			_, err := f.WriteString(fmt.Sprintf("%s\n", msg))
			if err != nil {
				log.Fatalf("log failed: %v", err)
			}
		}
	}()

	go func() {
		f, err := os.OpenFile("/reports/report.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		// c := 0
		spaces := regexp.MustCompile("[\t]+")
		// pdo_stmt_ := regexp.MustCompile("pdo_stmt_[0-9a-fA-F]{8}")
		multipleSpaces := regexp.MustCompile("    ")
		for {
			// select {
			// case msg1 := <-msgOut:
			msg := <-msgOut
			if msg.Type == "C" {
				// c = 0
				f.Close()
				f, err = os.OpenFile(fmt.Sprintf("/reports/report-%s.md", msg.Content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				// c = 0
				if err != nil {
					panic(err)
				}
				_, err := f.WriteString(fmt.Sprintf("# %s\n", msg.Content))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			} else {
				// case msg2 := <-msgOut:
				// c = c + 1
				m := spaces.ReplaceAll([]byte(msg.Content), []byte{' '})
				m = multipleSpaces.ReplaceAll(m, []byte{' '})
				_, err := f.WriteString(fmt.Sprintf("\n```sql\n%s\n```\n", string(m)))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			}
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {

			msgs <- fmt.Sprintf("recived ---->%#v\n", msg)
			if msg.Type == 'P' {
				if strings.Contains(string(msg.Content), "$1") {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content
					_ = newMsg.Int32()

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{112, 100, 111, 95, 115, 116, 109, 116, 95})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("msg ---->%s\n", string(newMsg))
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					msgs <- fmt.Sprintf("first string ---->%s\n", string(newMsg[:p+9]))
					newMsg = newMsg[p+9:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// // The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					// p = bytes.Index(newMsg, []byte{0})
					// // remove second string
					// msgs <- fmt.Sprintf("second string: message ---->%#v\n", newMsg[:p])
					// temp = string(newMsg[:p])
					// msgs <- fmt.Sprintf("second string: message temp ---->%s\n", temp)

				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content) - 1
						}
					}
					if sepIdx == -1 {
						sepIdx = len(msg.Content)
					}
					if selectIdx == -1 {
						selectIdx = 0
					}

					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
					// messages = append(messages, string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00")))
					msgOut <- msgStruct{Type: "M", Content: string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00"))}
				}
			} else {
				if msg.Type == 'B' && temp != "" && len(msg.Content) > 28 {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					msgs <- fmt.Sprintf("0 newMsg   ----->%#v\n", newMsg)

					if newMsg[0] == 0 {
						p := bytes.Index(newMsg, []byte{0})
						// remove first string
						msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
						msgs <- fmt.Sprintf("1.1 first string ---->%#v\n", newMsg[:p+1])
						newMsg = newMsg[p:]
						msgs <- fmt.Sprintf("0.1 newMsg   ----->%#v\n", newMsg)
					}
					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)

					t := newMsg.Int16()
					msgs <- fmt.Sprintf("vars types numbers ---->%#v\n", t)
					for t1 := 0; t1 == t; t1 = newMsg.Int16() {
						msgs <- fmt.Sprintf("22 newMsg   ----->%#v\n", newMsg)
					}

					msgs <- fmt.Sprintf("23 newMsg   ----->%#v\n", newMsg)
					totalVar := t
					// newMsg.Int16()
					vars := make(map[int]string)
					var varsIdx []int
					if (totalVar == 0 && len(newMsg) > 4) || totalVar > len(newMsg) {
						msgs <- fmt.Sprintf("23.1 newMsg   ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("0 totalVar  ----->%d\n", totalVar)
						for totalVar := 0; totalVar != 0 && totalVar < len(newMsg); totalVar = newMsg.Int16() {
							msgs <- fmt.Sprintf("24 newMsg   ----->%#v\n", newMsg)
							msgs <- fmt.Sprintf("1 totalVar  ----->%d\n", totalVar)
						}
					}
					//
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int16()
					// }
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int32()
					// }
					msgs <- fmt.Sprintf("totalVar   ----->%d\n", totalVar)
					for i := 0; i < totalVar; i++ {
						msgs <- fmt.Sprintf("2 newMsg   ----->%#v\n", newMsg)
						varLen := newMsg.Int32()
						// var1 := newMsg.Next(4)
						// // fmt.Printf("aa   -----> %#v\n", aa)
						// // fmt.Printf("aa bits ----->%8b\n", aa[len(aa)-1])
						// varLen := int(binary.BigEndian.Uint32(var1))
						// if varLen > len(newMsg) {
						// 	varLen = int(binary.BigEndian.Uint16(var1[:2]))
						// }
						msgs <- fmt.Sprintf("varLen ----->%v\n", varLen)
						msgs <- fmt.Sprintf("newMsg   ----->%#v\n", newMsg)
						if varLen > len(newMsg) {
							varLen = len(newMsg) - 4
							msgs <- fmt.Sprintf("1 varLen ----->%v\n", varLen)
							msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)
						}
						vars[i] = string(newMsg.Next(varLen))
						msgs <- fmt.Sprintf("vars   ----->%#v\n", vars)
						varsIdx = append(varsIdx, i)
						msgs <- fmt.Sprintf("varIdx  ----->%#v\n", varsIdx)
					}

					sort.Sort(sort.Reverse(sort.IntSlice(varsIdx)))
					for _, k := range varsIdx {
						// messages = append(messages, strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(newMsg[k+1])), -1))
						temp = strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(vars[k])), -1)
						msgs <- fmt.Sprintf("message subst k ----->%v\n", k)
						msgs <- fmt.Sprintf("message subst newMsg ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("message subst msg ----->%v\n", vars[k+1])
						msgs <- fmt.Sprintf("message subst temp ----->%v\n", temp)
						msgs <- fmt.Sprintf("message subst param %s ----->%v\n", fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", vars[k]))
					}
					msgs <- fmt.Sprintf("end message  ----->%v\n", temp)
					// msgOut <- msgStruct{Type: "M", Content: temp}
					// } else {
				}
				msgOut <- msgStruct{Type: "M", Content: temp}
				temp = ""
			}
		}
	}()

	proxy.Start(localHost, dbHostname, dbPort, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<commit_msg>Update<commit_after>package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"

	// "database/sql"

	_ "github.com/lib/pq"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":5432", "puerto local para escuchar")
	dbHostname    = flag.String("h", "localhost", "hostname del servidor PostgreSQL")
	dbPort        = flag.String("r", "5432", "puerto del servidor PostgreSQL")
	dbName        = flag.String("d", "dbname", "nombre de la base de datos")
	dbUsername    = flag.String("u", "username", "usuario para acceder al servidor PostgreSQL")
	dbPassword    = flag.String("p", "password", "password para acceder al servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	// messages      = []string{}
)

type msgStruct struct {
	Type    string
	Content string
}

var (
	db *sql.DB
)

func main() {
	flag.Parse()
	// dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
	// 	*dbUsername, *dbPassword, *dbName)
	// db, err := sql.Open("postgres", dbinfo)

	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	msgOut := make(chan msgStruct)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			inFile, _ := os.Open("canales_list.txt")
			defer inFile.Close()
			scanner := bufio.NewScanner(inFile)
			scanner.Split(bufio.ScanLines)

			for scanner.Scan() {
				time.Sleep(time.Second * 1)
				// messages = []string{}
				// fmt.Println(scanner.Text())
				// msgOut <- fmt.Sprintf("# %s\n", scanner.Text())
				msgOut <- msgStruct{Type: "C", Content: scanner.Text()}
				_, _, errs := gorequest.New().Get(fmt.Sprintf("%s%s", *remoteService, scanner.Text())).End()
				if errs != nil {
					log.Fatalf("log failed: %v", errs)
				}
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		f, err := os.OpenFile("/all.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		for msg := range msgs {
			// fmt.Println(msg)
			_, err := f.WriteString(fmt.Sprintf("%s\n", msg))
			if err != nil {
				log.Fatalf("log failed: %v", err)
			}
		}
	}()

	go func() {
		f, err := os.OpenFile("/reports/report.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		// c := 0
		spaces := regexp.MustCompile("[\t]+")
		// pdo_stmt_ := regexp.MustCompile("pdo_stmt_[0-9a-fA-F]{8}")
		multipleSpaces := regexp.MustCompile("    ")
		for {
			// select {
			// case msg1 := <-msgOut:
			msg := <-msgOut
			if msg.Type == "C" {
				// c = 0
				f.Close()
				f, err = os.OpenFile(fmt.Sprintf("/reports/report-%s.md", msg.Content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				// c = 0
				if err != nil {
					panic(err)
				}
				_, err := f.WriteString(fmt.Sprintf("# %s\n", msg.Content))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			} else {
				// case msg2 := <-msgOut:
				// c = c + 1
				m := spaces.ReplaceAll([]byte(msg.Content), []byte{' '})
				m = multipleSpaces.ReplaceAll(m, []byte{' '})
				_, err := f.WriteString(fmt.Sprintf("\n```sql\n%s\n```\n", string(m)))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			}
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			msgs <- fmt.Sprintf("received ---->%#v\n", msg)
			if msg.Type == byte('P') {
				if strings.Contains(string(msg.Content), "$1") {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content
					_ = newMsg.Int32()

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{112, 100, 111, 95, 115, 116, 109, 116, 95})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("msg ---->%s\n", string(newMsg))
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					msgs <- fmt.Sprintf("first string ---->%s\n", string(newMsg[:p+9]))
					newMsg = newMsg[p+9:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// // The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					// p = bytes.Index(newMsg, []byte{0})
					// // remove second string
					// msgs <- fmt.Sprintf("second string: message ---->%#v\n", newMsg[:p])
					// temp = string(newMsg[:p])
					// msgs <- fmt.Sprintf("second string: message temp ---->%s\n", temp)

				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content) - 1
						}
					}
					if sepIdx == -1 {
						sepIdx = len(msg.Content)
					}
					if selectIdx == -1 {
						selectIdx = 0
					}

					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
					// messages = append(messages, string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00")))
					msgOut <- msgStruct{Type: "M", Content: string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00"))}
				}
			} else {
				if msg.Type == byte('B') && temp != "" && len(msg.Content) > 28 {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					msgs <- fmt.Sprintf("0 newMsg   ----->%#v\n", newMsg)

					if newMsg[0] == 0 {
						p := bytes.Index(newMsg, []byte{0})
						// remove first string
						msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
						msgs <- fmt.Sprintf("1.1 first string ---->%#v\n", newMsg[:p+1])
						newMsg = newMsg[p:]
						msgs <- fmt.Sprintf("0.1 newMsg   ----->%#v\n", newMsg)
					}
					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)

					t := newMsg.Int16()
					msgs <- fmt.Sprintf("vars types numbers ---->%#v\n", t)
					for t1 := 0; t1 == t; t1 = newMsg.Int16() {
						msgs <- fmt.Sprintf("22 newMsg   ----->%#v\n", newMsg)
					}

					msgs <- fmt.Sprintf("23 newMsg   ----->%#v\n", newMsg)
					totalVar := t
					// newMsg.Int16()
					vars := make(map[int]string)
					var varsIdx []int
					if (totalVar == 0 && len(newMsg) > 4) || totalVar > len(newMsg) {
						msgs <- fmt.Sprintf("23.1 newMsg   ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("0 totalVar  ----->%d\n", totalVar)
						for totalVar := 0; totalVar != 0 && totalVar < len(newMsg); totalVar = newMsg.Int16() {
							msgs <- fmt.Sprintf("24 newMsg   ----->%#v\n", newMsg)
							msgs <- fmt.Sprintf("1 totalVar  ----->%d\n", totalVar)
						}
					}
					//
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int16()
					// }
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int32()
					// }
					msgs <- fmt.Sprintf("totalVar   ----->%d\n", totalVar)
					for i := 0; i < totalVar; i++ {
						msgs <- fmt.Sprintf("2 newMsg   ----->%#v\n", newMsg)
						varLen := newMsg.Int32()
						// var1 := newMsg.Next(4)
						// // fmt.Printf("aa   -----> %#v\n", aa)
						// // fmt.Printf("aa bits ----->%8b\n", aa[len(aa)-1])
						// varLen := int(binary.BigEndian.Uint32(var1))
						// if varLen > len(newMsg) {
						// 	varLen = int(binary.BigEndian.Uint16(var1[:2]))
						// }
						msgs <- fmt.Sprintf("varLen ----->%v\n", varLen)
						msgs <- fmt.Sprintf("newMsg   ----->%#v\n", newMsg)
						if varLen > len(newMsg) {
							varLen = len(newMsg) - 4
							msgs <- fmt.Sprintf("1 varLen ----->%v\n", varLen)
							msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)
						}
						vars[i] = string(newMsg.Next(varLen))
						msgs <- fmt.Sprintf("vars   ----->%#v\n", vars)
						varsIdx = append(varsIdx, i)
						msgs <- fmt.Sprintf("varIdx  ----->%#v\n", varsIdx)
					}

					sort.Sort(sort.Reverse(sort.IntSlice(varsIdx)))
					for _, k := range varsIdx {
						// messages = append(messages, strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(newMsg[k+1])), -1))
						temp = strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(vars[k])), -1)
						msgs <- fmt.Sprintf("message subst k ----->%v\n", k)
						msgs <- fmt.Sprintf("message subst newMsg ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("message subst msg ----->%v\n", vars[k+1])
						msgs <- fmt.Sprintf("message subst temp ----->%v\n", temp)
						msgs <- fmt.Sprintf("message subst param %s ----->%v\n", fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", vars[k]))
					}
					msgs <- fmt.Sprintf("end message  ----->%v\n", temp)
					// msgOut <- msgStruct{Type: "M", Content: temp}
					// } else {
				}
				msgOut <- msgStruct{Type: "M", Content: temp}
				temp = ""
			}
		}
	}()

	proxy.Start(localHost, dbHostname, dbPort, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<|endoftext|>


<commit_before>package models

type User struct {
    Id       int    `name:"id" type:"int" null:"NOT NULL" extra:"PRIMARY"`
    Login    string `name:"login" type:"text" null:"NOT NULL" extra:""`
    Pass     string `name:"pass" type:"text" null:"NOT NULL" extra:""`
    Salt     string `name:"salt" type:"text" null:"NOT NULL" extra:""`
    Role     string `name:"role" type:"text" null:"NOT NULL" extra:""`
    Hash     string `name:"hash" type:"text" null:"NULL" extra:""`
    PersonId int    `name:"person_id" type:"int" null:"NOT NULL" extra:"REFERENCES" refTable:"persons" refField:"id" refFieldShow:"fname"`
}

func (c *ModelManager) Users() *UsersModel {
    model := new(UsersModel)

    model.TableName = "users"
    model.Caption = "Пользователи"

    model.Columns = []string{"id", "login", "role", "person_id"}
    model.ColNames = []string{"ID", "Логин", "Роль", "Персона"}

    model.Fields = new(User)
    model.WherePart = make(map[string]interface{}, 0)
    model.OrderBy = "id"
    model.Limit = "ALL"
    model.Offset = 0

    model.Sub = false
    model.SubTable = nil
    model.SubField = ""

    return model
}

type UsersModel struct {
    Entity
}
<commit_msg>user's model: fix fields<commit_after>package models

type User struct {
    Id    int    `name:"id" type:"int" null:"NOT NULL" extra:"PRIMARY"`
    Login string `name:"login" type:"text" null:"NOT NULL" extra:""`
    Pass  string `name:"pass" type:"text" null:"NOT NULL" extra:""`
    Salt  string `name:"salt" type:"text" null:"NOT NULL" extra:""`
    Role  string `name:"role" type:"text" null:"NOT NULL" extra:""`
    Hash  string `name:"hash" type:"text" null:"NULL" extra:""`
}

func (c *ModelManager) Users() *UsersModel {
    model := new(UsersModel)

    model.TableName = "users"
    model.Caption = "Пользователи"

    model.Columns = []string{"id", "login", "role"}
    model.ColNames = []string{"ID", "Логин", "Роль"}

    model.Fields = new(User)
    model.WherePart = make(map[string]interface{}, 0)
    model.OrderBy = "id"
    model.Limit = "ALL"
    model.Offset = 0

    model.Sub = false
    model.SubTable = nil
    model.SubField = ""

    return model
}

type UsersModel struct {
    Entity
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/google/go-github/github"
)

// MirroredPR contains the upstream and downstream PR ids
type MirroredPR struct {
	DownstreamID int
	UpstreamID   int
}

// PRMirror contains various different variables
type PRMirror struct {
	GitHubClient  *github.Client
	Context       *context.Context
	Configuration *Config
	Database      *Database
	GitLock       *SpinLock
}

// GitHubEventMonitor passes in an instance of the PRMirror struct to all HTTP calls to the webhook listener
type GitHubEventMonitor struct {
	Mirrorer PRMirror
}

// HandleEvent handles github events and acts like an event handler
func (p PRMirror) HandleEvent(event *github.Event) {
	seenEvent, _ := p.Database.SeenEvent(event.GetID())
	if seenEvent {
		return
	}

	eventType := event.GetType()
	if eventType != "PullRequestEvent" {
		return
	}

	prEvent := github.PullRequestEvent{}
	err := json.Unmarshal(event.GetRawPayload(), &prEvent)
	if err != nil {
		panic(err)
	}

	p.HandlePREvent(&prEvent)
	p.Database.AddEvent(event.GetID())
}

func (p PRMirror) HandlePREvent(prEvent *github.PullRequestEvent) {
	repoName := prEvent.Repo.GetName()
	repoOwner := prEvent.Repo.Organization.GetName()
	prEventURL := prEvent.PullRequest.GetURL()

	if repoName != p.Configuration.UpstreamRepo {
		log.Warningf("Ignoring PR Event: %s because %s != %s\n", prEventURL, repoName, p.Configuration.UpstreamRepo)
		return
	} else if repoOwner != p.Configuration.UpstreamOwner {
		log.Warningf("Ignoring PR Event: %s because %s != %s\n", prEventURL, repoOwner, p.Configuration.UpstreamOwner)
		return
	}

	log.Debugf("Handling PR Event: %s\n", prEventURL)

	prAction := prEvent.GetAction()
	if prAction == "closed" && prEvent.PullRequest.GetMerged() == true {
		prID, err := p.MirrorPR(prEvent.PullRequest)
		if err != nil {
			log.Errorf("Error while creating a new PR: %s\n", err.Error())
		} else {
			p.AddLabels(prID, []string{"Upstream PR Merged"})
			p.Database.StoreMirror(prID, prEvent.PullRequest.GetNumber())
		}
	}
}

// RunEventScraper runs the GitHub repo event API scraper
func (p PRMirror) RunEventScraper() {
	for {
		events, pollInterval, err := p.GetRepoEvents()
		if err == nil {
			for _, event := range events {
				p.HandleEvent(event)
			}
		}

		log.Debugf("Sleeping for %d as specified by GitHub\n", pollInterval)
		time.Sleep(time.Duration(pollInterval) * time.Second)
	}
}

// ServeHTTP handles HTTP requests to the webhook endpoint
func (s GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	payload, err := github.ValidatePayload(r, []byte(s.Mirrorer.Configuration.WebhookSecret))
	if err != nil {
		log.Errorf("Error validating the payload\n")
		return
	}
	event, err := github.ParseWebHook(github.WebHookType(r), payload)
	if err != nil {
		log.Errorf("Error parsing the payload\n")
	}

	switch event := event.(type) {
	case *github.PullRequestEvent:
		s.Mirrorer.HandlePREvent(event)
	}
}

// RunWebhookListener acts a webhook listener which GitHub will call with events
func (p PRMirror) RunWebhookListener() {
	server := GitHubEventMonitor{Mirrorer: p}
	err := http.ListenAndServe(fmt.Sprintf(":%d", p.Configuration.WebhookPort), server)
	log.Fatal(err)
}

// MirrorPR will mirror a PR from an upstream to the downstream
func (p PRMirror) MirrorPR(pr *github.PullRequest) (int, error) {
	p.GitLock.Lock()
	defer p.GitLock.Unlock()

	log.Infof("Mirroring PR [%d]: %s from %s\n", pr.GetNumber(), pr.GetTitle(), pr.User.GetLogin())

	cmd := exec.Command(fmt.Sprintf("%s%s", p.Configuration.RepoPath, p.Configuration.ToolPath), strconv.Itoa(pr.GetNumber()), pr.GetTitle())
	cmd.Dir = p.Configuration.RepoPath
	cmdoutput, err := cmd.CombinedOutput()
	if err != nil {
		panic(err)
	}

	logpath := fmt.Sprintf("./logs/upstream-merge-%d.log", pr.GetNumber())
	ioutil.WriteFile(logpath, cmdoutput, 0600)
	log.Debugf("Wrote log to %s\n", logpath)

	base := "master"
	head := fmt.Sprintf("upstream-merge-%d", pr.GetNumber())
	maintainerCanModify := true // We are the owner of the PR so we can specify this as true
	title := fmt.Sprintf("[MIRROR] %s", pr.GetTitle())
	body := fmt.Sprintf("Original PR: %s\n--------------------\n%s", pr.GetHTMLURL(), strings.Replace(pr.GetBody(), "@", "@ ", -1))

	newPR := github.NewPullRequest{}
	newPR.Title = &title
	newPR.Body = &body
	newPR.Base = &base
	newPR.Head = &head
	newPR.MaintainerCanModify = &maintainerCanModify

	pr, _, err = p.GitHubClient.PullRequests.Create(*p.Context, p.Configuration.DownstreamOwner, p.Configuration.DownstreamRepo, &newPR)
	if err != nil {
		return 0, err
	}

	if strings.Contains(string(cmdoutput), "Rejected hunk") {
		p.AddLabels(pr.GetNumber(), []string{"Auto Merge Rejections"})
	}

	return pr.GetNumber(), nil
}
<commit_msg>Fucking...<commit_after>package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/google/go-github/github"
)

// MirroredPR contains the upstream and downstream PR ids
type MirroredPR struct {
	DownstreamID int
	UpstreamID   int
}

// PRMirror contains various different variables
type PRMirror struct {
	GitHubClient  *github.Client
	Context       *context.Context
	Configuration *Config
	Database      *Database
	GitLock       *SpinLock
}

// GitHubEventMonitor passes in an instance of the PRMirror struct to all HTTP calls to the webhook listener
type GitHubEventMonitor struct {
	Mirrorer PRMirror
}

// HandleEvent handles github events and acts like an event handler
func (p PRMirror) HandleEvent(event *github.Event) {
	seenEvent, _ := p.Database.SeenEvent(event.GetID())
	if seenEvent {
		return
	}

	eventType := event.GetType()
	if eventType != "PullRequestEvent" {
		return
	}

	prEvent := github.PullRequestEvent{}
	err := json.Unmarshal(event.GetRawPayload(), &prEvent)
	if err != nil {
		panic(err)
	}

	p.HandlePREvent(&prEvent)
	p.Database.AddEvent(event.GetID())
}

func (p PRMirror) HandlePREvent(prEvent *github.PullRequestEvent) {
	prEventURL := prEvent.PullRequest.GetURL()
	log.Debugf("Handling PR Event: %s\n", prEventURL)

	prAction := prEvent.GetAction()
	if prAction == "closed" && prEvent.PullRequest.GetMerged() == true {
		prID, err := p.MirrorPR(prEvent.PullRequest)
		if err != nil {
			log.Errorf("Error while creating a new PR: %s\n", err.Error())
		} else {
			repoName := prEvent.Repo.GetName()
			repoOwner := prEvent.Repo.Organization.GetName()

			if repoName != p.Configuration.DownstreamRepo {
				log.Warningf("Ignoring PR Event: %s because %s != %s\n", prEventURL, repoName, p.Configuration.UpstreamRepo)
				return
			} else if repoOwner != p.Configuration.DownstreamOwner {
				log.Warningf("Ignoring PR Event: %s because %s != %s\n", prEventURL, repoOwner, p.Configuration.UpstreamOwner)
				return
			}

			p.AddLabels(prID, []string{"Upstream PR Merged"})
			p.Database.StoreMirror(prID, prEvent.PullRequest.GetNumber())
		}
	}
}

// RunEventScraper runs the GitHub repo event API scraper
func (p PRMirror) RunEventScraper() {
	for {
		events, pollInterval, err := p.GetRepoEvents()
		if err == nil {
			for _, event := range events {
				p.HandleEvent(event)
			}
		}

		log.Debugf("Sleeping for %d as specified by GitHub\n", pollInterval)
		time.Sleep(time.Duration(pollInterval) * time.Second)
	}
}

// ServeHTTP handles HTTP requests to the webhook endpoint
func (s GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	payload, err := github.ValidatePayload(r, []byte(s.Mirrorer.Configuration.WebhookSecret))
	if err != nil {
		log.Errorf("Error validating the payload\n")
		return
	}
	event, err := github.ParseWebHook(github.WebHookType(r), payload)
	if err != nil {
		log.Errorf("Error parsing the payload\n")
	}

	switch event := event.(type) {
	case *github.PullRequestEvent:
		s.Mirrorer.HandlePREvent(event)
	}
}

// RunWebhookListener acts a webhook listener which GitHub will call with events
func (p PRMirror) RunWebhookListener() {
	server := GitHubEventMonitor{Mirrorer: p}
	err := http.ListenAndServe(fmt.Sprintf(":%d", p.Configuration.WebhookPort), server)
	log.Fatal(err)
}

// MirrorPR will mirror a PR from an upstream to the downstream
func (p PRMirror) MirrorPR(pr *github.PullRequest) (int, error) {
	p.GitLock.Lock()
	defer p.GitLock.Unlock()

	log.Infof("Mirroring PR [%d]: %s from %s\n", pr.GetNumber(), pr.GetTitle(), pr.User.GetLogin())

	cmd := exec.Command(fmt.Sprintf("%s%s", p.Configuration.RepoPath, p.Configuration.ToolPath), strconv.Itoa(pr.GetNumber()), pr.GetTitle())
	cmd.Dir = p.Configuration.RepoPath
	cmdoutput, err := cmd.CombinedOutput()
	if err != nil {
		panic(err)
	}

	logpath := fmt.Sprintf("./logs/upstream-merge-%d.log", pr.GetNumber())
	ioutil.WriteFile(logpath, cmdoutput, 0600)
	log.Debugf("Wrote log to %s\n", logpath)

	base := "master"
	head := fmt.Sprintf("upstream-merge-%d", pr.GetNumber())
	maintainerCanModify := true // We are the owner of the PR so we can specify this as true
	title := fmt.Sprintf("[MIRROR] %s", pr.GetTitle())
	body := fmt.Sprintf("Original PR: %s\n--------------------\n%s", pr.GetHTMLURL(), strings.Replace(pr.GetBody(), "@", "@ ", -1))

	newPR := github.NewPullRequest{}
	newPR.Title = &title
	newPR.Body = &body
	newPR.Base = &base
	newPR.Head = &head
	newPR.MaintainerCanModify = &maintainerCanModify

	pr, _, err = p.GitHubClient.PullRequests.Create(*p.Context, p.Configuration.DownstreamOwner, p.Configuration.DownstreamRepo, &newPR)
	if err != nil {
		return 0, err
	}

	if strings.Contains(string(cmdoutput), "Rejected hunk") {
		p.AddLabels(pr.GetNumber(), []string{"Auto Merge Rejections"})
	}

	return pr.GetNumber(), nil
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
	"fmt"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"knative.dev/pkg/apis"
	"knative.dev/pkg/apis/duck"
	duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// GcpPubSubSource is the Schema for the gcppubsubsources API.
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
// +kubebuilder:categories=all,knative,eventing,sources
type GcpPubSubSource struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   GcpPubSubSourceSpec   `json:"spec,omitempty"`
	Status GcpPubSubSourceStatus `json:"status,omitempty"`
}

// Check that GcpPubSubSource can be validated and can be defaulted.
var _ runtime.Object = (*GcpPubSubSource)(nil)

// Check that GcpPubSubSource will be checked for immutable fields.
var _ apis.Immutable = (*GcpPubSubSource)(nil)

// Check that GcpPubSubSource implements the Conditions duck type.
var _ = duck.VerifyType(&GcpPubSubSource{}, &duckv1alpha1.Conditions{})

// GcpPubSubSourceSpec defines the desired state of the GcpPubSubSource.
type GcpPubSubSourceSpec struct {
	// GcpCredsSecret is the credential to use to poll the GCP PubSub Subscription. It is not used
	// to create or delete the Subscription, only to poll it. The value of the secret entry must be
	// a service account key in the JSON format (see
	// https://cloud.google.com/iam/docs/creating-managing-service-account-keys).
	GcpCredsSecret corev1.SecretKeySelector `json:"gcpCredsSecret,omitempty"`

	// GoogleCloudProject is the ID of the Google Cloud Project that the PubSub Topic exists in.
	GoogleCloudProject string `json:"googleCloudProject,omitempty"`

	// Topic is the ID of the GCP PubSub Topic to Subscribe to. It must be in the form of the
	// unique identifier within the project, not the entire name. E.g. it must be 'laconia', not
	// 'projects/my-gcp-project/topics/laconia'.
	Topic string `json:"topic,omitempty"`

	// Sink is a reference to an object that will resolve to a domain name to use as the sink.
	// +optional
	Sink *corev1.ObjectReference `json:"sink,omitempty"`

	// Transformer is a reference to an object that will resolve to a domain name to use as the transformer.
	// +optional
	Transformer *corev1.ObjectReference `json:"transformer,omitempty"`

	// ServiceAccoutName is the name of the ServiceAccount that will be used to run the Receive
	// Adapter Deployment.
	ServiceAccountName string `json:"serviceAccountName,omitempty"`
}

const (
	// GcpPubSubSourceEventType is the GcpPubSub CloudEvent type, in case PubSub doesn't send a
	// CloudEvent itself.
	GcpPubSubSourceEventType = "google.pubsub.topic.publish"
)

// GcpPubSubEventSource returns the GcpPubSub CloudEvent source value.
func GcpPubSubEventSource(googleCloudProject, topic string) string {
	return fmt.Sprintf("//pubsub.googleapis.com/%s/topics/%s", googleCloudProject, topic)
}

const (
	// GcpPubSubConditionReady has status True when the GcpPubSubSource is ready to send events.
	GcpPubSubConditionReady = duckv1alpha1.ConditionReady

	// GcpPubSubConditionSinkProvided has status True when the GcpPubSubSource has been configured with a sink target.
	GcpPubSubConditionSinkProvided duckv1alpha1.ConditionType = "SinkProvided"

	// GcpPubSubConditionTransformerProvided has status True when the GcpPubSubSource has been configured with a transformer target.
	GcpPubSubConditionTransformerProvided duckv1alpha1.ConditionType = "TransformerProvided"

	// GcpPubSubConditionDeployed has status True when the GcpPubSubSource has had it's receive adapter deployment created.
	GcpPubSubConditionDeployed duckv1alpha1.ConditionType = "Deployed"

	// GcpPubSubConditionSubscribed has status True when a GCP PubSub Subscription has been created pointing at the created receive adapter deployment.
	GcpPubSubConditionSubscribed duckv1alpha1.ConditionType = "Subscribed"

	// GcpPubSubConditionEventTypesProvided has status True when the GcpPubSubSource has been configured with event types.
	GcpPubSubConditionEventTypesProvided duckv1alpha1.ConditionType = "EventTypesProvided"
)

var gcpPubSubSourceCondSet = duckv1alpha1.NewLivingConditionSet(
	GcpPubSubConditionSinkProvided,
	GcpPubSubConditionDeployed,
	GcpPubSubConditionSubscribed)

// GcpPubSubSourceStatus defines the observed state of GcpPubSubSource.
type GcpPubSubSourceStatus struct {
	// inherits duck/v1alpha1 Status, which currently provides:
	// * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller.
	// * Conditions - the latest available observations of a resource's current state.
	duckv1alpha1.Status `json:",inline"`

	// SinkURI is the current active sink URI that has been configured for the GcpPubSubSource.
	// +optional
	SinkURI string `json:"sinkUri,omitempty"`

	// TransformerURI is the current active transformer URI that has been configured for the GcpPubSubSource.
	// +optional
	TransformerURI string `json:"transformerUri,omitempty"`
}

// GetCondition returns the condition currently associated with the given type, or nil.
func (s *GcpPubSubSourceStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition {
	return gcpPubSubSourceCondSet.Manage(s).GetCondition(t)
}

// IsReady returns true if the resource is ready overall.
func (s *GcpPubSubSourceStatus) IsReady() bool {
	return gcpPubSubSourceCondSet.Manage(s).IsHappy()
}

// InitializeConditions sets relevant unset conditions to Unknown state.
func (s *GcpPubSubSourceStatus) InitializeConditions() {
	gcpPubSubSourceCondSet.Manage(s).InitializeConditions()
}

// MarkSink sets the condition that the source has a sink configured.
func (s *GcpPubSubSourceStatus) MarkSink(uri string) {
	s.SinkURI = uri
	if len(uri) > 0 {
		gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionSinkProvided)
	} else {
		gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.")
	}
}

// MarkSink sets the condition that the source has a transformer configured.
func (s *GcpPubSubSourceStatus) MarkTransformer(uri string) {
	s.TransformerURI = uri
	if len(uri) > 0 {
		gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionTransformerProvided)
	} else {
		gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionTransformerProvided, "TransformerEmpty", "Transformer has resolved to empty.")
	}
}

// MarkNoSink sets the condition that the source does not have a sink configured.
func (s *GcpPubSubSourceStatus) MarkNoSink(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionSinkProvided, reason, messageFormat, messageA...)
}

// MarkNoTransformer sets the condition that the source does not have a transformer configured.
func (s *GcpPubSubSourceStatus) MarkNoTransformer(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionTransformerProvided, reason, messageFormat, messageA...)
}

// MarkDeployed sets the condition that the source has been deployed.
func (s *GcpPubSubSourceStatus) MarkDeployed() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionDeployed)
}

// MarkDeploying sets the condition that the source is deploying.
func (s *GcpPubSubSourceStatus) MarkDeploying(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionDeployed, reason, messageFormat, messageA...)
}

// MarkNotDeployed sets the condition that the source has not been deployed.
func (s *GcpPubSubSourceStatus) MarkNotDeployed(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionDeployed, reason, messageFormat, messageA...)
}

func (s *GcpPubSubSourceStatus) MarkSubscribed() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionSubscribed)
}

// MarkEventTypes sets the condition that the source has created its event types.
func (s *GcpPubSubSourceStatus) MarkEventTypes() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionEventTypesProvided)
}

// MarkNoEventTypes sets the condition that the source does not its event types configured.
func (s *GcpPubSubSourceStatus) MarkNoEventTypes(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionEventTypesProvided, reason, messageFormat, messageA...)
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// GcpPubSubSourceList contains a list of GcpPubSubSources.
type GcpPubSubSourceList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []GcpPubSubSource `json:"items"`
}

func init() {
	SchemeBuilder.Register(&GcpPubSubSource{}, &GcpPubSubSourceList{})
}
<commit_msg>fix API to HTML ref doc build (#480)<commit_after>/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
	"fmt"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"knative.dev/pkg/apis"
	"knative.dev/pkg/apis/duck"
	duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// GcpPubSubSource is the Schema for the gcppubsubsources API.
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
// +kubebuilder:categories=all,knative,eventing,sources
type GcpPubSubSource struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   GcpPubSubSourceSpec   `json:"spec,omitempty"`
	Status GcpPubSubSourceStatus `json:"status,omitempty"`
}

// Check that GcpPubSubSource can be validated and can be defaulted.
var _ runtime.Object = (*GcpPubSubSource)(nil)

// Check that GcpPubSubSource will be checked for immutable fields.
var _ apis.Immutable = (*GcpPubSubSource)(nil)

// Check that GcpPubSubSource implements the Conditions duck type.
var _ = duck.VerifyType(&GcpPubSubSource{}, &duckv1alpha1.Conditions{})

// GcpPubSubSourceSpec defines the desired state of the GcpPubSubSource.
type GcpPubSubSourceSpec struct {
	// GcpCredsSecret is the credential to use to poll the GCP PubSub Subscription. It is not used
	// to create or delete the Subscription, only to poll it. The value of the secret entry must be
	// a service account key in the JSON format
	// ( see https://cloud.google.com/iam/docs/creating-managing-service-account-keys ).
	GcpCredsSecret corev1.SecretKeySelector `json:"gcpCredsSecret,omitempty"`

	// GoogleCloudProject is the ID of the Google Cloud Project that the PubSub Topic exists in.
	GoogleCloudProject string `json:"googleCloudProject,omitempty"`

	// Topic is the ID of the GCP PubSub Topic to Subscribe to. It must be in the form of the
	// unique identifier within the project, not the entire name. E.g. it must be 'laconia', not
	// 'projects/my-gcp-project/topics/laconia'.
	Topic string `json:"topic,omitempty"`

	// Sink is a reference to an object that will resolve to a domain name to use as the sink.
	// +optional
	Sink *corev1.ObjectReference `json:"sink,omitempty"`

	// Transformer is a reference to an object that will resolve to a domain name to use as the transformer.
	// +optional
	Transformer *corev1.ObjectReference `json:"transformer,omitempty"`

	// ServiceAccoutName is the name of the ServiceAccount that will be used to run the Receive
	// Adapter Deployment.
	ServiceAccountName string `json:"serviceAccountName,omitempty"`
}

const (
	// GcpPubSubSourceEventType is the GcpPubSub CloudEvent type, in case PubSub doesn't send a
	// CloudEvent itself.
	GcpPubSubSourceEventType = "google.pubsub.topic.publish"
)

// GcpPubSubEventSource returns the GcpPubSub CloudEvent source value.
func GcpPubSubEventSource(googleCloudProject, topic string) string {
	return fmt.Sprintf("//pubsub.googleapis.com/%s/topics/%s", googleCloudProject, topic)
}

const (
	// GcpPubSubConditionReady has status True when the GcpPubSubSource is ready to send events.
	GcpPubSubConditionReady = duckv1alpha1.ConditionReady

	// GcpPubSubConditionSinkProvided has status True when the GcpPubSubSource has been configured with a sink target.
	GcpPubSubConditionSinkProvided duckv1alpha1.ConditionType = "SinkProvided"

	// GcpPubSubConditionTransformerProvided has status True when the GcpPubSubSource has been configured with a transformer target.
	GcpPubSubConditionTransformerProvided duckv1alpha1.ConditionType = "TransformerProvided"

	// GcpPubSubConditionDeployed has status True when the GcpPubSubSource has had it's receive adapter deployment created.
	GcpPubSubConditionDeployed duckv1alpha1.ConditionType = "Deployed"

	// GcpPubSubConditionSubscribed has status True when a GCP PubSub Subscription has been created pointing at the created receive adapter deployment.
	GcpPubSubConditionSubscribed duckv1alpha1.ConditionType = "Subscribed"

	// GcpPubSubConditionEventTypesProvided has status True when the GcpPubSubSource has been configured with event types.
	GcpPubSubConditionEventTypesProvided duckv1alpha1.ConditionType = "EventTypesProvided"
)

var gcpPubSubSourceCondSet = duckv1alpha1.NewLivingConditionSet(
	GcpPubSubConditionSinkProvided,
	GcpPubSubConditionDeployed,
	GcpPubSubConditionSubscribed)

// GcpPubSubSourceStatus defines the observed state of GcpPubSubSource.
type GcpPubSubSourceStatus struct {
	// inherits duck/v1alpha1 Status, which currently provides:
	// * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller.
	// * Conditions - the latest available observations of a resource's current state.
	duckv1alpha1.Status `json:",inline"`

	// SinkURI is the current active sink URI that has been configured for the GcpPubSubSource.
	// +optional
	SinkURI string `json:"sinkUri,omitempty"`

	// TransformerURI is the current active transformer URI that has been configured for the GcpPubSubSource.
	// +optional
	TransformerURI string `json:"transformerUri,omitempty"`
}

// GetCondition returns the condition currently associated with the given type, or nil.
func (s *GcpPubSubSourceStatus) GetCondition(t duckv1alpha1.ConditionType) *duckv1alpha1.Condition {
	return gcpPubSubSourceCondSet.Manage(s).GetCondition(t)
}

// IsReady returns true if the resource is ready overall.
func (s *GcpPubSubSourceStatus) IsReady() bool {
	return gcpPubSubSourceCondSet.Manage(s).IsHappy()
}

// InitializeConditions sets relevant unset conditions to Unknown state.
func (s *GcpPubSubSourceStatus) InitializeConditions() {
	gcpPubSubSourceCondSet.Manage(s).InitializeConditions()
}

// MarkSink sets the condition that the source has a sink configured.
func (s *GcpPubSubSourceStatus) MarkSink(uri string) {
	s.SinkURI = uri
	if len(uri) > 0 {
		gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionSinkProvided)
	} else {
		gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionSinkProvided, "SinkEmpty", "Sink has resolved to empty.")
	}
}

// MarkSink sets the condition that the source has a transformer configured.
func (s *GcpPubSubSourceStatus) MarkTransformer(uri string) {
	s.TransformerURI = uri
	if len(uri) > 0 {
		gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionTransformerProvided)
	} else {
		gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionTransformerProvided, "TransformerEmpty", "Transformer has resolved to empty.")
	}
}

// MarkNoSink sets the condition that the source does not have a sink configured.
func (s *GcpPubSubSourceStatus) MarkNoSink(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionSinkProvided, reason, messageFormat, messageA...)
}

// MarkNoTransformer sets the condition that the source does not have a transformer configured.
func (s *GcpPubSubSourceStatus) MarkNoTransformer(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionTransformerProvided, reason, messageFormat, messageA...)
}

// MarkDeployed sets the condition that the source has been deployed.
func (s *GcpPubSubSourceStatus) MarkDeployed() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionDeployed)
}

// MarkDeploying sets the condition that the source is deploying.
func (s *GcpPubSubSourceStatus) MarkDeploying(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkUnknown(GcpPubSubConditionDeployed, reason, messageFormat, messageA...)
}

// MarkNotDeployed sets the condition that the source has not been deployed.
func (s *GcpPubSubSourceStatus) MarkNotDeployed(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionDeployed, reason, messageFormat, messageA...)
}

func (s *GcpPubSubSourceStatus) MarkSubscribed() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionSubscribed)
}

// MarkEventTypes sets the condition that the source has created its event types.
func (s *GcpPubSubSourceStatus) MarkEventTypes() {
	gcpPubSubSourceCondSet.Manage(s).MarkTrue(GcpPubSubConditionEventTypesProvided)
}

// MarkNoEventTypes sets the condition that the source does not its event types configured.
func (s *GcpPubSubSourceStatus) MarkNoEventTypes(reason, messageFormat string, messageA ...interface{}) {
	gcpPubSubSourceCondSet.Manage(s).MarkFalse(GcpPubSubConditionEventTypesProvided, reason, messageFormat, messageA...)
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// GcpPubSubSourceList contains a list of GcpPubSubSources.
type GcpPubSubSourceList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []GcpPubSubSource `json:"items"`
}

func init() {
	SchemeBuilder.Register(&GcpPubSubSource{}, &GcpPubSubSourceList{})
}
<|endoftext|>


<commit_before>package models

import (
	"encoding/json"
	"koding/db/mongodb/modelhelper"
	"strconv"
	"time"

	"github.com/jinzhu/gorm"
)

const (
	ChannelRequestMessage_TYPE_INVITE = "invite"
	ChannelRequestMessage_TYPE_JOIN   = "join"
	ChannelRequestMessage_TYPE_LEAVE  = "leave"
	ChannelRequestMessage_TYPE_REJECT = "reject"
	ChannelRequestMessage_TYPE_KICK   = "kick"
	ChannelRequestMessage_TYPE_INIT   = "initiate"
)

type ChannelRequest struct {
	Body            string      `json:"body"`
	Name            string      `json:"name"`
	Payload         gorm.Hstore `json:"payload,omitempty"`
	GroupName       string      `json:"groupName"`
	Recipients      []string
	AccountId       int64  `json:"accountId,string"`
	ChannelId       int64  `json:"channelId,string"`
	RequestData     string `json:"requestData"`
	ClientRequestId string `json:"ClientRequestId"`
	Purpose         string `json:"purpose"`
	TypeConstant    string `json:"type"`
}

func (p *ChannelRequest) Create() (*ChannelContainer, error) {
	// validate the request
	if err := p.validate(); err != nil {
		return nil, err
	}

	// fetch participants
	participantIds, err := p.obtainParticipantIds()
	if err != nil {
		return nil, err
	}

	// create the channel
	c := NewChannel()
	c.GroupName = p.GroupName
	c.CreatorId = p.AccountId
	c.Name = RandomName()
	c.TypeConstant = p.TypeConstant
	c.Purpose = p.Purpose
	c.Payload = p.Payload

	if p.Name != "" {
		c.Name = p.Name
	}

	// all topic channels under koding, should be public
	if c.TypeConstant == Channel_TYPE_TOPIC && c.GroupName == Channel_KODING_NAME {
		c.PrivacyConstant = Channel_PRIVACY_PUBLIC
	}

	if err := c.Create(); err != nil {
		return nil, err
	}

	groupChannel, err := Cache.Channel.ByGroupName(c.GroupName)
	if err != nil {
		return nil, err
	}

	// add participants to the channel
	for _, participantId := range participantIds {
		// users should be in regarding group channel
		if err := checkForGroupParticipation(groupChannel, participantId); err != nil {
			return nil, err
		}

		cp, err := c.AddParticipant(participantId)
		if err != nil {
			continue
		}

		if participantId != p.AccountId {
			continue
		}

		// do not show unread count to the creator of the private message
		oneSecondLater := time.Now().UTC().Add(time.Second * 1)
		// do not show unread count as 1 to user
		err = cp.RawUpdateLastSeenAt(oneSecondLater)
		if err != nil {
			return nil, err
		}
	}

	typeConstant := ChannelMessage_TYPE_PRIVATE_MESSAGE
	if p.TypeConstant == Channel_TYPE_TOPIC {
		typeConstant = ChannelMessage_TYPE_POST
	}

	return p.buildInitContainer(c, participantIds, typeConstant)
}

func checkForGroupParticipation(groupChannel *Channel, participantId int64) error {
	// everyone is a member of koding group
	if groupChannel.GroupName == Channel_KODING_NAME {
		return nil
	}

	isParticipant, err := groupChannel.IsParticipant(participantId)
	if err != nil {
		return nil
	}

	if !isParticipant {
		return ErrCannotOpenChannel
	}

	return nil
}

func (p *ChannelRequest) buildInitContainer(c *Channel, participantIds []int64, typeConstant string) (*ChannelContainer, error) {

	np := &ChannelRequest{}
	*np = *p
	lastMessage, err := p.AddInitActivity(c, participantIds)
	if err != nil {
		return nil, err
	}

	if np.Body != "" {
		var err error
		// create private message

		lastMessage, err = p.createActivity(c, typeConstant)
		if err != nil {
			return nil, err
		}
	}

	cmc, err := p.buildContainer(c, lastMessage)
	if err != nil {
		return nil, err
	}

	participantOldIds, err := FetchAccountOldsIdByIdsFromCache(participantIds)
	if err != nil {
		return nil, err
	}

	// set participant count
	cmc.ParticipantCount = len(participantIds)
	// set preview
	cmc.ParticipantsPreview = participantOldIds

	return cmc, nil
}

func (p *ChannelRequest) Send() (*ChannelContainer, error) {
	if err := p.validate(); err != nil {
		return nil, err
	}

	if p.ChannelId == 0 {
		return nil, ErrChannelIdIsNotSet
	}

	// check channel existence
	c, err := Cache.Channel.ById(p.ChannelId)
	if err != nil {
		return nil, err
	}

	// check if sender is whether a participant of conversation
	canOpen, err := c.CanOpen(p.AccountId)
	if err != nil {
		return nil, err
	}

	c.UpdatedAt = time.Now()
	// expensive
	if err = c.Update(); err != nil {
		return nil, err
	}

	if !canOpen {
		return nil, ErrCannotOpenChannel
	}

	cp, err := c.FetchParticipant(p.AccountId)
	if err != nil {
		return nil, err
	}

	oneSecondLater := time.Now().UTC().Add(time.Second * 1)
	// do not show unread count as 1 to user
	err = cp.RawUpdateLastSeenAt(oneSecondLater)
	if err != nil {
		return nil, err
	}

	typeConstant := ChannelMessage_TYPE_PRIVATE_MESSAGE

	if c.TypeConstant == Channel_TYPE_TOPIC {
		typeConstant = ChannelMessage_TYPE_POST
	}

	cm, err := p.createActivity(c, typeConstant)
	if err != nil {
		return nil, err
	}

	return p.buildContainer(c, cm)
}

func (p *ChannelRequest) Clone() *ChannelRequest {
	clone := new(ChannelRequest)
	*clone = *p

	return clone
}

func (p *ChannelRequest) AddJoinActivity(c *Channel, addedBy int64) error {
	if p.AccountId != addedBy && addedBy != 0 {
		addedByStr := strconv.FormatInt(addedBy, 10)
		p.Payload["addedBy"] = &addedByStr
	}

	_, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)

	return err
}

func (p *ChannelRequest) AddLeaveActivity(c *Channel) error {
	_, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)

	return err
}

func (p *ChannelRequest) AddInitActivity(c *Channel, participantIds []int64) (*ChannelMessage, error) {
	if len(participantIds) == 0 {
		return nil, nil
	}

	if p.Payload == nil {
		p.Payload = gorm.Hstore{}
	}

	if len(participantIds) > 0 {
		payload := formatParticipantIds(participantIds)
		p.Payload["initialParticipants"] = &payload
		activity := ChannelRequestMessage_TYPE_INIT
		p.Payload["systemType"] = &activity
	}

	cm, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)
	if err != nil {
		return nil, err
	}

	return cm, nil
}

func (p *ChannelRequest) SetSystemMessageType(systemType string) {
	if p.Payload == nil {
		p.Payload = gorm.Hstore{}
	}

	if systemType != "" {
		p.Payload["systemType"] = &systemType
	}
}

func (p *ChannelRequest) createActivity(c *Channel, typeConstant string) (*ChannelMessage, error) {
	cm, err := p.createMessage(c.Id, typeConstant)
	if err != nil {
		return nil, err
	}

	// add message to the channel
	cm.ClientRequestId = p.ClientRequestId
	_, err = c.AddMessage(cm)
	if err != nil {
		return nil, err
	}

	return cm, nil
}

func (p *ChannelRequest) buildContainer(c *Channel, cm *ChannelMessage) (*ChannelContainer, error) {

	lastMessageContainer, err := cm.BuildEmptyMessageContainer()
	if err != nil {
		return nil, err
	}

	cm, err = lastMessageContainer.Message.PopulatePayload()
	if err != nil {
		return nil, err
	}

	cmc := NewChannelContainer()
	cmc.Channel = c
	cmc.IsParticipant = true
	cmc.LastMessage = lastMessageContainer
	cmc.LastMessage.Message = cm
	cmc.LastMessage.Message.ClientRequestId = p.ClientRequestId
    cmc.AddAccountOldId()
    if cmc.Err != nil {
        return nil, cmc.Err
    }

	return cmc, nil
}

func (p *ChannelRequest) validate() error {
	if p.AccountId == 0 {
		return ErrAccountIdIsNotSet
	}

	if p.GroupName == "" {
		p.GroupName = Channel_KODING_NAME
	}

	if p.TypeConstant == "" {
		p.TypeConstant = Channel_TYPE_PRIVATE_MESSAGE
	}

	return nil
}

// TODO refactor this function to use postgres
func (p *ChannelRequest) obtainParticipantIds() ([]int64, error) {
	participantIds := make([]int64, len(p.Recipients))
	for i, participantName := range p.Recipients {
		// get account from mongo
		account, err := modelhelper.GetAccount(participantName)
		if err != nil {
			return nil, err
		}

		a := NewAccount()
		socialApiId, _ := account.GetSocialApiId()

		a.Id = socialApiId
		a.OldId = account.Id.Hex()
		a.Nick = account.Profile.Nickname
		// fetch or create social api id
		if a.Id == 0 {
			if err := a.FetchOrCreate(); err != nil {
				return nil, err
			}
		}
		participantIds[i] = a.Id
	}

	// append creator to the recipients
	participantIds = prependCreatorId(participantIds, p.AccountId)

	// author and atleast one recipient should be in the
	// recipient list
	if len(participantIds) < 1 {
		// user can send private message to themself
		return nil, ErrRecipientsNotDefined
	}

	return participantIds, nil
}

func prependCreatorId(participants []int64, authorId int64) []int64 {
	participantIds := make([]int64, 0)
	participantIds = append(participantIds, authorId)

	for _, participant := range participants {
		if participant == authorId {
			continue
		}

		participantIds = append(participantIds, participant)
	}

	return participantIds
}

func (p *ChannelRequest) createMessage(channelId int64, typeConstant string) (*ChannelMessage, error) {
	cm := NewChannelMessage()
	cm.Body = getBody(p, typeConstant)
	cm.TypeConstant = typeConstant
	cm.AccountId = p.AccountId
	cm.InitialChannelId = channelId
	cm.Payload = p.Payload

	if err := cm.Create(); err != nil {
		return nil, err
	}

	return cm, nil
}

func getBody(p *ChannelRequest, typeConstant string) string {
	if typeConstant == ChannelMessage_TYPE_SYSTEM {
		return "system"
	}

	return p.Body
}

func formatParticipantIds(participantIds []int64) string {
	pids := make([]string, len(participantIds)-1)

	// exclude first participant since it is the private channel owner
	for i, participantId := range participantIds[1:len(participantIds)] {
		accountId := strconv.FormatInt(participantId, 10)
		pids[i] = accountId
	}

	result, _ := json.Marshal(pids)

	return string(result)
}
<commit_msg>Socialapi: fix indentation problem<commit_after>package models

import (
	"encoding/json"
	"koding/db/mongodb/modelhelper"
	"strconv"
	"time"

	"github.com/jinzhu/gorm"
)

const (
	ChannelRequestMessage_TYPE_INVITE = "invite"
	ChannelRequestMessage_TYPE_JOIN   = "join"
	ChannelRequestMessage_TYPE_LEAVE  = "leave"
	ChannelRequestMessage_TYPE_REJECT = "reject"
	ChannelRequestMessage_TYPE_KICK   = "kick"
	ChannelRequestMessage_TYPE_INIT   = "initiate"
)

type ChannelRequest struct {
	Body            string      `json:"body"`
	Name            string      `json:"name"`
	Payload         gorm.Hstore `json:"payload,omitempty"`
	GroupName       string      `json:"groupName"`
	Recipients      []string
	AccountId       int64  `json:"accountId,string"`
	ChannelId       int64  `json:"channelId,string"`
	RequestData     string `json:"requestData"`
	ClientRequestId string `json:"ClientRequestId"`
	Purpose         string `json:"purpose"`
	TypeConstant    string `json:"type"`
}

func (p *ChannelRequest) Create() (*ChannelContainer, error) {
	// validate the request
	if err := p.validate(); err != nil {
		return nil, err
	}

	// fetch participants
	participantIds, err := p.obtainParticipantIds()
	if err != nil {
		return nil, err
	}

	// create the channel
	c := NewChannel()
	c.GroupName = p.GroupName
	c.CreatorId = p.AccountId
	c.Name = RandomName()
	c.TypeConstant = p.TypeConstant
	c.Purpose = p.Purpose
	c.Payload = p.Payload

	if p.Name != "" {
		c.Name = p.Name
	}

	// all topic channels under koding, should be public
	if c.TypeConstant == Channel_TYPE_TOPIC && c.GroupName == Channel_KODING_NAME {
		c.PrivacyConstant = Channel_PRIVACY_PUBLIC
	}

	if err := c.Create(); err != nil {
		return nil, err
	}

	groupChannel, err := Cache.Channel.ByGroupName(c.GroupName)
	if err != nil {
		return nil, err
	}

	// add participants to the channel
	for _, participantId := range participantIds {
		// users should be in regarding group channel
		if err := checkForGroupParticipation(groupChannel, participantId); err != nil {
			return nil, err
		}

		cp, err := c.AddParticipant(participantId)
		if err != nil {
			continue
		}

		if participantId != p.AccountId {
			continue
		}

		// do not show unread count to the creator of the private message
		oneSecondLater := time.Now().UTC().Add(time.Second * 1)
		// do not show unread count as 1 to user
		err = cp.RawUpdateLastSeenAt(oneSecondLater)
		if err != nil {
			return nil, err
		}
	}

	typeConstant := ChannelMessage_TYPE_PRIVATE_MESSAGE
	if p.TypeConstant == Channel_TYPE_TOPIC {
		typeConstant = ChannelMessage_TYPE_POST
	}

	return p.buildInitContainer(c, participantIds, typeConstant)
}

func checkForGroupParticipation(groupChannel *Channel, participantId int64) error {
	// everyone is a member of koding group
	if groupChannel.GroupName == Channel_KODING_NAME {
		return nil
	}

	isParticipant, err := groupChannel.IsParticipant(participantId)
	if err != nil {
		return nil
	}

	if !isParticipant {
		return ErrCannotOpenChannel
	}

	return nil
}

func (p *ChannelRequest) buildInitContainer(c *Channel, participantIds []int64, typeConstant string) (*ChannelContainer, error) {

	np := &ChannelRequest{}
	*np = *p
	lastMessage, err := p.AddInitActivity(c, participantIds)
	if err != nil {
		return nil, err
	}

	if np.Body != "" {
		var err error
		// create private message

		lastMessage, err = p.createActivity(c, typeConstant)
		if err != nil {
			return nil, err
		}
	}

	cmc, err := p.buildContainer(c, lastMessage)
	if err != nil {
		return nil, err
	}

	participantOldIds, err := FetchAccountOldsIdByIdsFromCache(participantIds)
	if err != nil {
		return nil, err
	}

	// set participant count
	cmc.ParticipantCount = len(participantIds)
	// set preview
	cmc.ParticipantsPreview = participantOldIds

	return cmc, nil
}

func (p *ChannelRequest) Send() (*ChannelContainer, error) {
	if err := p.validate(); err != nil {
		return nil, err
	}

	if p.ChannelId == 0 {
		return nil, ErrChannelIdIsNotSet
	}

	// check channel existence
	c, err := Cache.Channel.ById(p.ChannelId)
	if err != nil {
		return nil, err
	}

	// check if sender is whether a participant of conversation
	canOpen, err := c.CanOpen(p.AccountId)
	if err != nil {
		return nil, err
	}

	c.UpdatedAt = time.Now()
	// expensive
	if err = c.Update(); err != nil {
		return nil, err
	}

	if !canOpen {
		return nil, ErrCannotOpenChannel
	}

	cp, err := c.FetchParticipant(p.AccountId)
	if err != nil {
		return nil, err
	}

	oneSecondLater := time.Now().UTC().Add(time.Second * 1)
	// do not show unread count as 1 to user
	err = cp.RawUpdateLastSeenAt(oneSecondLater)
	if err != nil {
		return nil, err
	}

	typeConstant := ChannelMessage_TYPE_PRIVATE_MESSAGE

	if c.TypeConstant == Channel_TYPE_TOPIC {
		typeConstant = ChannelMessage_TYPE_POST
	}

	cm, err := p.createActivity(c, typeConstant)
	if err != nil {
		return nil, err
	}

	return p.buildContainer(c, cm)
}

func (p *ChannelRequest) Clone() *ChannelRequest {
	clone := new(ChannelRequest)
	*clone = *p

	return clone
}

func (p *ChannelRequest) AddJoinActivity(c *Channel, addedBy int64) error {
	if p.AccountId != addedBy && addedBy != 0 {
		addedByStr := strconv.FormatInt(addedBy, 10)
		p.Payload["addedBy"] = &addedByStr
	}

	_, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)

	return err
}

func (p *ChannelRequest) AddLeaveActivity(c *Channel) error {
	_, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)

	return err
}

func (p *ChannelRequest) AddInitActivity(c *Channel, participantIds []int64) (*ChannelMessage, error) {
	if len(participantIds) == 0 {
		return nil, nil
	}

	if p.Payload == nil {
		p.Payload = gorm.Hstore{}
	}

	if len(participantIds) > 0 {
		payload := formatParticipantIds(participantIds)
		p.Payload["initialParticipants"] = &payload
		activity := ChannelRequestMessage_TYPE_INIT
		p.Payload["systemType"] = &activity
	}

	cm, err := p.createActivity(c, ChannelMessage_TYPE_SYSTEM)
	if err != nil {
		return nil, err
	}

	return cm, nil
}

func (p *ChannelRequest) SetSystemMessageType(systemType string) {
	if p.Payload == nil {
		p.Payload = gorm.Hstore{}
	}

	if systemType != "" {
		p.Payload["systemType"] = &systemType
	}
}

func (p *ChannelRequest) createActivity(c *Channel, typeConstant string) (*ChannelMessage, error) {
	cm, err := p.createMessage(c.Id, typeConstant)
	if err != nil {
		return nil, err
	}

	// add message to the channel
	cm.ClientRequestId = p.ClientRequestId
	_, err = c.AddMessage(cm)
	if err != nil {
		return nil, err
	}

	return cm, nil
}

func (p *ChannelRequest) buildContainer(c *Channel, cm *ChannelMessage) (*ChannelContainer, error) {

	lastMessageContainer, err := cm.BuildEmptyMessageContainer()
	if err != nil {
		return nil, err
	}

	cm, err = lastMessageContainer.Message.PopulatePayload()
	if err != nil {
		return nil, err
	}

	cmc := NewChannelContainer()
	cmc.Channel = c
	cmc.IsParticipant = true
	cmc.LastMessage = lastMessageContainer
	cmc.LastMessage.Message = cm
	cmc.LastMessage.Message.ClientRequestId = p.ClientRequestId
	cmc.AddAccountOldId()
	if cmc.Err != nil {
		return nil, cmc.Err
	}

	return cmc, nil
}

func (p *ChannelRequest) validate() error {
	if p.AccountId == 0 {
		return ErrAccountIdIsNotSet
	}

	if p.GroupName == "" {
		p.GroupName = Channel_KODING_NAME
	}

	if p.TypeConstant == "" {
		p.TypeConstant = Channel_TYPE_PRIVATE_MESSAGE
	}

	return nil
}

// TODO refactor this function to use postgres
func (p *ChannelRequest) obtainParticipantIds() ([]int64, error) {
	participantIds := make([]int64, len(p.Recipients))
	for i, participantName := range p.Recipients {
		// get account from mongo
		account, err := modelhelper.GetAccount(participantName)
		if err != nil {
			return nil, err
		}

		a := NewAccount()
		socialApiId, _ := account.GetSocialApiId()

		a.Id = socialApiId
		a.OldId = account.Id.Hex()
		a.Nick = account.Profile.Nickname
		// fetch or create social api id
		if a.Id == 0 {
			if err := a.FetchOrCreate(); err != nil {
				return nil, err
			}
		}
		participantIds[i] = a.Id
	}

	// append creator to the recipients
	participantIds = prependCreatorId(participantIds, p.AccountId)

	// author and atleast one recipient should be in the
	// recipient list
	if len(participantIds) < 1 {
		// user can send private message to themself
		return nil, ErrRecipientsNotDefined
	}

	return participantIds, nil
}

func prependCreatorId(participants []int64, authorId int64) []int64 {
	participantIds := make([]int64, 0)
	participantIds = append(participantIds, authorId)

	for _, participant := range participants {
		if participant == authorId {
			continue
		}

		participantIds = append(participantIds, participant)
	}

	return participantIds
}

func (p *ChannelRequest) createMessage(channelId int64, typeConstant string) (*ChannelMessage, error) {
	cm := NewChannelMessage()
	cm.Body = getBody(p, typeConstant)
	cm.TypeConstant = typeConstant
	cm.AccountId = p.AccountId
	cm.InitialChannelId = channelId
	cm.Payload = p.Payload

	if err := cm.Create(); err != nil {
		return nil, err
	}

	return cm, nil
}

func getBody(p *ChannelRequest, typeConstant string) string {
	if typeConstant == ChannelMessage_TYPE_SYSTEM {
		return "system"
	}

	return p.Body
}

func formatParticipantIds(participantIds []int64) string {
	pids := make([]string, len(participantIds)-1)

	// exclude first participant since it is the private channel owner
	for i, participantId := range participantIds[1:len(participantIds)] {
		accountId := strconv.FormatInt(participantId, 10)
		pids[i] = accountId
	}

	result, _ := json.Marshal(pids)

	return string(result)
}
<|endoftext|>