docker Standard_init_linux.go:178 exec user process caused no such file

docker error on window 10 when you try to use entrypoint.sh

read error log in container by

docker logs {your_container}

1.Standard_init_linux.go:178 exec user process caused no such file
2. /bin/sh^M : bad interpreter or

fixed by:

COPY custom-init.sh /custom-init.sh
RUN chmod +x /custom-init.sh
#Converting file /custom-init.sh to Unix format ...
RUN apt-get install dos2unix
RUN dos2unix /custom-init.sh
ENTRYPOINT ["/custom-init.sh"]
Posted in docker | Leave a comment

เทคโนโลยีไลฟ์สตรีมมิ่งกับการถ่ายทอดสดกีฬา

ไลฟ์สตรีมมิ่ง ทางเลือกใหม่สำหรับการรับชมกีฬา

ด้วยเทคโนโลยีต่างๆในปัจจุบันที่ได้พัฒนาขึ้นไปเป็นอย่างมากจากในอดีต ทำให้ทุกวันนี้ทางเลือกต่างๆของผู้บริโภค ไม่ว่าจะเป็นกลุ่มไหน หรือมีความต้องการแบบใด ก็มีทางเลือกในการรับบริการกันเพิ่มมากยิ่งขึ้น โดยเฉพาะในวงการกีฬาที่มีช่องทางในการรับชมและเชียร์กีฬาสำหรับเหล่าคนรักกีฬาที่เพิ่มขึ้นเป็นอย่างมากจากในอดีต ซึ่งเทคโนโลยีที่ก้าวเข้ามามีส่วนสำคัญที่เรากำลังจะพูดถึงกันนั้นก็คือ ไลฟ์สตรีมมิ่ง หรือที่เรารู้จักกันในนามการทายทอดสดผ่านอินเทอร์เน็ตนั่นเอง
ไลฟ์สตรีมมิ่ง เป็นเทคโนโลยีตัวใหม่ที่เกิดขึ้นจากการพัฒนาของอินเทอร์เน็ต และระบบการถ่ายทอดสด ทำให้ทางผู้ให้บริการสามารถทายทอดสดสัญญาณทั้งภาพและเสียงของการแข่งขันกีฬาต่างๆ มาให้ผู้ใช้บริการอย่างเราๆได้รับชมกันแบบสดๆ ผ่านทางสัญญาณอินเทอร์เน็ต ทำให้คนรักกีฬาสามารถรับชมและเชียร์กีฬาที่ตัวเองชื่นชอบได้อย่างสะดวกง่ายดายตลอด 24 ชั่วโมง หรือว่าจะเป็นในส่วนของนักพนันที่เป็นลูกค้าของเว็บไซต์เกมออนไลน์ที่สามารถดูกีฬาไปพร้อมกับรับชมบทวิเคราะห์ของทาง M88main ได้แม่นยำแน่นอน ทำให้ในทุกการเดิมพันของคุณนั้นจะได้ผลลัพธ์ที่แน่นอนมากยิ่งขึ้น ด้วยเหตุนี้เองจึงทำให้การไลฟ์สตรีมมิ่งกลายมาเป็นอีกหนึ่งทางเลือกใหม่สำหรับการชมกีฬาที่หลายๆคนชื่นชอบ และเริ่มแพร่หลายความนิยมมากยิ่งขึ้นเรื่อยๆ
หากใครที่อยากจะสัมผัสเทคโนโลยีนี้กันบ้าง หรืออยากจะลองใช้งานไลฟ์สตรีมมิ่งดู ก็เริ่มต้นได้ง่ายๆ เพียงแค่คุณหาผู้ให้บริการที่ทำการถ่ายทอดสดกีฬาชนิดต่างๆที่คุณกำลังสนใจอยู่ หรืออยากจะรับชม และทำการเลือกรับชมการถ่ายทอดสดของผู้ให้บริการเหล่านั้น เพียงเท่านี้คุณก็สามารถรับชมการไลฟ์สตรีมมิ่งกีฬาชนิดต่างๆได้แบบวินาทีต่อวินาทีแล้ว เพราะการไลฟ์สตรีมมิ่งถูกออกแบบมาให้อำนวยความสะดวกแก่ผู้ใช้งานและยังมีความรวดเร็ว ทำให้ผู้ใช้งานอย่างเราๆไม่ต้องกังวลเรื่องการติดตั้งโปรแกรมที่ยุ่งยากวุ่นวาย หรือการตั้งค่าระบบอะไรที่ซับซ้อน ดังนั้นหากใครที่กำลังกังวลกับเรื่องราวเหล่านี้อยู่ ก็หมดความกังวลไปได้และเตรียมตัวไปใช้งานไลฟ์สตรีมมิ่งให้เต็มที่กันดีกว่า

Posted in ไม่มีหมวดหมู่ | Leave a comment

spring boot JPA relation @OneToMany,@ManyToOne

วิธีการทำ Relation ใน JPA ของ Spring boot สมมติเรามี 2 Entity มี Relation กันแบบ OneToMany และ ManyToOne

ขั้นแรกเราต้องทำ Table Relation ใน Database ตัวอย่างคำสั่งนี้เป็นการทำ Foreign key ใน MySQL

ALTER TABLE authentication
ADD FOREIGN KEY (profile_uid)
REFERENCES profile(profile_uid)

สำหรับ 1 Profile มีหลาย Authentication จะต้องใช้ Annonation (@OneToMany) และใช้ @JsonManagedReference สำหรับจัดการไม่ให้เกิด Infinity Loop

@Entity
@Table(name = "profile")
public class Profile {

    //ย้ายพวก @Id, @GeneratedValue, @Column ลงไปอยู่บนหัว method สำหรับการจะทำ JPA Relation
    //for many to one , one to many relation
    //If you move also annotations from id-field
    //to the getId-method (for both entities), problem is solved.

    @JsonProperty("uid")
    private Long uid;

    @JsonProperty("first_name")
    private String firstName;

    @JsonProperty("last_name")
    private String lastName;

    @JsonProperty("display_name")
    private String displayName;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("birthday")
    private Date birthday;

    @JsonProperty("email")
    private String email;

    @JsonProperty("email_contact")
    private String emailContact;

    @JsonProperty("gender")
    private Long gender;

    @JsonProperty("status")
    private Long status;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("created_at")
    private Date created_at;

    @JsonProperty("created_ip")
    private String created_ip;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("updated_at")
    private Date updated_at;

    @JsonProperty("updated_ip")
    private String updated_ip;

    private Set<Authentication> authentications;

    @Id
    @Column(name  = "profile_uid")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    @Column(name  = "profile_first_name")
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name  = "profile_last_name")
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Column(name  = "profile_display_name")
    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    @Column(name  = "profile_birthday")
    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Column(name  = "profile_email")
    public String getEmail() {
        return email;
    }

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

    @Column(name  = "profile_email_contact")
    public String getEmailContact() {
        return emailContact;
    }

    public void setEmailContact(String emailContact) {
        this.emailContact = emailContact;
    }

    @Column(name  = "profile_gender")
    public Long getGender() {
        return gender;
    }

    public void setGender(Long gender) {
        this.gender = gender;
    }

    @Column(name  = "profile_status")
    public Long getStatus() {
        return status;
    }

    public void setStatus(Long status) {
        this.status = status;
    }

    @Column(name  = "created_at")
    public Date getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Date created_at) {
        this.created_at = created_at;
    }

    @Column(name  = "created_ip")
    public String getCreated_ip() {
        return created_ip;
    }

    public void setCreated_ip(String created_ip) {
        this.created_ip = created_ip;
    }

    @Column(name  = "updated_at")
    public Date getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(Date updated_at) {
        this.updated_at = updated_at;
    }

    @Column(name  = "updated_ip")
    public String getUpdated_ip() {
        return updated_ip;
    }

    public void setUpdated_ip(String updated_ip) {
        this.updated_ip = updated_ip;
    }

    @OneToMany(targetEntity=Authentication.class,mappedBy = "profile",fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JsonManagedReference
    public Set<Authentication> getAuthentications() {
        return authentications;
    }

    public void setAuthentications(Set<Authentication> authentications) {
        this.authentications = authentications;
    }
}

สำหรับ Authentication ที่ผูกกลับไปที่ Profile จะต้องใช้ Annonation (@ManyToOne) และใช้ @JsonBackReference สำหรับจัดการไม่ให้เกิด Infinity Loop

@Entity
@Table(name = "authentication")
public class Authentication {

    //ย้ายพวก @Id, @GeneratedValue, @Column ลงไปอยู่บนหัว method สำหรับการจะทำ JPA Relation
    //for many to one , one to many relation
    //If you move also annotations from id-field
    //to the getId-method (for both entities), problem is solved.

    @JsonProperty("auth_id")
    private Long authId;

    @JsonProperty("account")
    private String account;

    @JsonProperty("client_id")
    private String clientId;

    @JsonProperty("password")
    private String password;

    @JsonProperty("password_oneway")
    private String passwordOneway;

    @JsonProperty("operator")
    private String operator;

    @JsonProperty("status")
    private Long status;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("verified_date")
    private Date verified_date;

    @JsonProperty("verified_status")
    private Long verified_status;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("last_login")
    private Date last_login;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("created_at")
    private Date created_at;

    @JsonProperty("created_ip")
    private String created_ip;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("updated_at")
    private Date updated_at;

    @JsonProperty("updated_ip")
    private String updated_ip;

    @JsonProperty("auth_type_id")
    private Long auth_type_id;

    @JsonProperty("profile")
    private Profile profile;

    @Column(name  = "client_id")
    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name  = "auth_id")
    public Long getAuthId() {
        return authId;
    }

    public void setAuthId(Long authId) {
        this.authId = authId;
    }

    @Column(name  = "auth_account")
    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    @Column(name  = "auth_password")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Column(name  = "auth_password_oneway")
    public String getPasswordOneway() {
        return passwordOneway;
    }

    public void setPasswordOneway(String passwordOneway) {
        this.passwordOneway = passwordOneway;
    }

    @Column(name  = "auth_operator")
    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    @Column(name  = "auth_status")
    public Long getStatus() {
        return status;
    }

    public void setStatus(Long status) {
        this.status = status;
    }

    @Column(name  = "auth_verified_date")
    public Date getVerified_date() {
        return verified_date;
    }

    public void setVerified_date(Date verified_date) {
        this.verified_date = verified_date;
    }

    @Column(name  = "auth_verified_status")
    public Long getVerified_status() {
        return verified_status;
    }

    public void setVerified_status(Long verified_status) {
        this.verified_status = verified_status;
    }

    @Column(name  = "auth_last_login")
    public Date getLast_login() {
        return last_login;
    }

    public void setLast_login(Date last_login) {
        this.last_login = last_login;
    }

    @Column(name  = "created_at")
    public Date getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Date created_at) {
        this.created_at = created_at;
    }

    @Column(name  = "created_ip")
    public String getCreated_ip() {
        return created_ip;
    }

    public void setCreated_ip(String created_ip) {
        this.created_ip = created_ip;
    }

    @Column(name  = "updated_at")
    public Date getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(Date updated_at) {
        this.updated_at = updated_at;
    }

    @Column(name  = "updated_ip")
    public String getUpdated_ip() {
        return updated_ip;
    }

    public void setUpdated_ip(String updated_ip) {
        this.updated_ip = updated_ip;
    }

    @Column(name  = "auth_type_id")
    public Long getAuth_type_id() {
        return auth_type_id;
    }

    public void setAuth_type_id(Long auth_type_id) {
        this.auth_type_id = auth_type_id;
    }

    @ManyToOne
    @JoinColumn(name = "profile_uid")
    @JsonBackReference
    public Profile getProfile() {
        return profile;
    }

    public void setProfile(Profile profile) {
        this.profile = profile;
    }

}

ตัวอย่าง Response เวลาเราเรียก ProfileRepository.findById(1); เราก็จะรู้ว่า profile_uid ที่มีค่า 1 มี authentication อะไรบ้าง

{"authentications":[{"auth_id":7,"account":"kongarn@gmail.com","client_id":"1","password":"9IUoxNtGh52hNaczc9pN0A==","password_oneway":"ee79976c9380d5e337fc1c095ece8c8f22f91f306ceeb161fa51fecede2c4ba1","operator":null,"status":1,"verified_date":null,"verified_status":1,"last_login":null,"created_at":1486314000000,"created_ip":null,"updated_at":null,"updated_ip":null,"auth_type_id":1}],"uid":1,"first_name":"Panupong","last_name":"Kongarn","display_name":"thenesta","birthday":634410000000,"email":"kongarn@gmail.com","email_contact":"kongarn@gmail.com","gender":2,"status":1,"created_at":1485882000000,"created_ip":"127.0.0.1","updated_at":null,"updated_ip":null}

ตัวอย่างวิธีการ save ข้อมูล ตัวอย่างทำการเรียกผ่าน RestController ง่ายๆเลย

@Transactional("transactionManager")
    @RequestMapping(value = "/testsave",  method = { RequestMethod.GET})
    public @ResponseBody
    String testsave(
            @RequestParam Map<String, String> allRequestParams
    ) throws TrueIDException, NoSuchAlgorithmException {
        java.util.Date date = new java.util.Date();

        long time = date.getTime();//timestamp in millisec
        java.sql.Date sqlDate = new java.sql.Date(time);
        java.sql.Time sqlTime = new java.sql.Time(time);

        try {
            Profile profile = new Profile();
            profile.setEmail("test@gmail.com");
            profile.setEmailContact("test@gmail.com");
            profile.setStatus(1L);
            profile.setCreated_ip("127.0.0.1");
            profile.setCreated_at(sqlDate);


            Authentication authentication = new Authentication();
            authentication.setAccount("test@gmail.com");
            authentication.setClientId("1");
            authentication.setProfile(profile);
            authentication.setStatus(1L);
            authentication.setPassword("xxx");
            authentication.setPasswordOneway("xxx");

            Set authentications = new HashSet<Authentication>(){{
                add(authentication);
            }};

            profile.setAuthentications(authentications);

            profileRepository.save(profile);


        } catch (Exception ex) {
            //throw new RuntimeException("Whoop! Somthing went wrong");
        }
        return "OK";
Posted in spring boot | Leave a comment

spring boot logback redis config environment profile

https://github.com/kmtong/logback-redis-appender Import this module to your project or add dependency

Default It write log by using redis rpush command (see in RedisAppender.java). you can change to use redis publish command if you want.

client.rpush(key, json);

setting redis config by environment profile (spring.profiles.active) in /resources/application-alpha.properties
/resources/application-staging.properties
/resources/application-production.properties

logback.redis.ip : localhost
logback.redis.port : 6379

in /resources/logback.xml

<configuration>
    <include resource="logback-${spring.profiles.active}.xml"/>
</configuration>

example in /resources/logback-alpha.xml

<?xml version="1.0" encoding="UTF-8"?>
<included>
    <appender name="redis" class="net.trueid.microservices.logback.RedisAppender">
         <source>mySource</source>
         <sourcePath>mySourcePath</sourcePath>
         <type>otp</type>
         <host>localhost</host>
         <port>6379</port>
         <key>yourkey</key>
    </appender>

    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{HH:mm:ss.SSS} [%thread] %level %logger - %msg%n</pattern>
        </layout>
    </appender>

    <root level="INFO">
        <appender-ref ref="stdout"/>
        <appender-ref ref="redis"/>
    </root>
</included>

How to write log to redis

private final Logger logger = LoggerFactory.getLogger(RedisAppender.class);
logger.info("your info");

Monitor your log in redis-cli

LINDEX {logback_key} {index}

example run spring boot with spring.actives.profile

spring-boot:run -Dspring.profiles.active=alpha
Posted in java, spring boot | Leave a comment

สอนวิธี live streaming youtube ด้วยโปรแกรม OBS Studio #1

สอนวิธี live stream youtube ด้วยโปรแกรม OBS Studio #1

รายละเอียดในคลิบนี้จะสอนวิธีใช้โปรแกรม OBS Studio ใช้ในการ live streaming ซึ่งสามารถ live ได้ทั้ง twitter , youtube และอื่นๆ นอกจากนี้ยังสอนการ setup audio , การ setup video และนำ key จาก youtube มาผูกกับตัวโปรแกรม

ขอขอบคุณเครดิต พี่แว่น fpsthailand ครับ

Posted in technology | Leave a comment