태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.


2009/12/02 01:47

빌드서버 구축 - 2008 Server Core + CruiseControl.NET + SVN 설치, 셋팅

Windows Server 2008 R2 Core 환경에 CruiseControl.NET을 설치하여 원격 Buil Server를 구축 하는 업무를 맏게 되었다.
일반 GUI환경에서의 설치방법이나 후기는 많은 편이어서 어렵지 않게 할 수 있는데 GUI가 없는 Server Core환경에서는 몇가지 요소때문에 곤란한 부분이 생긴다. PowerShell을 설치해서 사용하는등 개인적인 부분도 있으니 자신에게 필요한 부분인지 생각 해 보고 적용 하도록 하자.

  1. Windows Server 2008 R2 Core 버전 설치 (난 Standard버전을 설치 하였다.)

  2. .NET FrameWork 설치  
    start /w ocsetup NetFx2-ServerCore
    start /w ocsetup NetFx3-ServerCore
    start /w ocsetup NetFx2-ServerCore-WOW64
    start /w ocsetup NetFx3-ServerCore-WOW64

  3. PowerShell 설치
    start /w ocsetup MicrosoftWindowsPowerShell
  4. cmd대신 PowerShell을 기본으로 설정 하면 편리 하다.

  5. IIS 설치
    start /w ocsetup IIS-WebServerRole
    start /w ocsetup WAS-NetFxEnvironment
    start /w ocsetup IIS-ISAPIExtensions 
    start /w ocsetup IIS-ISAPIFilter 
    start /w ocsetup IIS-NetFxExtensibility
    start /w ocsetup IIS-ManagementService
    start /w ocsetup IIS-ASPNET

  6. Reboot
    shutdown -r

  7. Subversion Client 설치 (SVN 리포지터리의 소스를 받아서 Build하는 경우 해당)
    CollabNet Subversion Command-Line Client 를 설치 한다.
    설치 경로 C:\Program Files (x86)\CollabNet\Subversion Client를(svn.exe) Path에 등록 시키면 후에 편리하다.

  8. CruiseControl.NET 설치
    설치 옵션의 Web Dashboard를 꼭 설치 하도록 하자.

  9. CruiseControl.Net 서비스로 실행하기
    설치 중 CruiseControl를 Windows Service에 추가 하는것을 선택 했다면 (기본값) Windows Service로 사용할 수 있다.
    기본값은 시작 유형이 수동으로 되어 있기 때문에 Service가 꺼져 있다. 이것을 활성화 시키기 위해서는
     net start CCService

  10. Service의 시작 유형을 자동으로 바꾸기 위해서는 (PowerShell명령이다. cmd에서 하는 방법도 있다)
    PowerShell Set-Service CCService -startuptype Automatic

  11. IIS에 Web Dashboard 등록하기
    CruiseControl 설치시 IIS에 자동으로 Web Dashboard를 설치 해주는 옵션이 있지만 Windows Server 2008 R2 Core 버전에서는 적용이 되지 않는다. 그래서 수동으로 설치된 경로의 webdashboard 폴더를 응용 프로그램으로 등록 해 줘야 한다.
    여기서는 Default Web Site에 응용 프로그램으로 추가 하겠다. 명령을 참고하여 자신에게 맞게 적용하자.
    c:\Windows\System32\inetsrv\appcmd.exe add app /site.name:'Default Web Site' /path:/ccnet /physicalPath:"C:\Program Files (x86)\CruiseControl.NET\webdashboard"

    applicationPool부분을 꼭 손봐줘야 한다. 매우 중요하다.
    c:\Windows\System32\inetsrv\appcmd.exe set app "Default Web Site/ccnet" /applicationPool:"Classic .NET AppPool"

  12. 방화벽 설정
    CruiseControl 서버에 CCtray같은 클라이언트 프로그램으로 접속 하기 위해서는 서버측에 21234포트가 열려 있어야 한다.
    바람직한 방법은 방화벽의 인바운드 규칙에 21234포트를 추가 하는 것이다. Web Dashboard도 80번 포트가 아닌 다른 포트를 이용 한다면 같은 방법으로 추가 하자.
    netsh advfirewall firewall add rule name="allow CCnet" protocol=TCP dir=in localport=21234 action=allow

    외부에 노출 되지 않는 환경이고 하나씩 추가 하는 것이 귀찮다면 방화벽을 꺼버리자 (추천하지 않는다)
    netsh firewall set opmode disable

  13. 테스트
    설치가 완료 되었다. CruiseControl이 설치된 폴더로 가서 ccnet.exe를 직접 실행 시키거나 위에서 설명한데로 Windows Service로 CruiseControl를 실행한 상태에서 클라이언트 컴퓨터로 http://서버주소/ccnet 에 접속해 보자.
    에러 메세지 없이 다음과 같은 화면을 본다면 성공이다.

자세히 기술 하다보니 복잡해 보이지만 직접 진행 해 보면 그리 어려운 작업이 아니라는것을 느끼게 된다. CruiseControl를 설정하여 SVN, MSBuild를 사용하는 방법은 다음 포스트에서 진행 하겠다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2009/11/30 03:11

.NET(C#) Serialization , Deserialization


.NET(C#) Serialization , Deserialization

serialization 이란 개체를 저장하거나 전송할 수 있는 형태로 개체의 상태를 변환하는 프로세스 이다. 그리고 serialization과 반대로 다시 개체로 변환하는 것을 deserialization이라 한다.

serialization을 사용하는 가장 큰 이유는 개체의 상태를 저장소에 보존 했다가 나중에 똑같은 복사본을 다시 만들거나 한 응용프로그램 에서 다른 응용프로그램으로 개체를 전송하기 위해서 이다.

.NET Framework에서는 제공하는 serialize 방식은 크게 2가지로 나눌 수 있다.

l  이진 serialization : 형식 정확도를 유지 하므로 응용 프로그램의 여러 호출간에 개체 상태를 유지 하는데 유용하다. 개체를 스트림, 디스크, 메모리, 네트워크 등으로 serialize할 수 있다.

l  XML serialization public 속성과 필드만 serialize하며 형식 정확도를 유지하지 않는다. 데이터를 사용하는 응용프로그램을 제한하지 않고 데이터를 제공하거나 사용하려고 할 때 유용하다. XML은 공개 표준이기 때문에 웹을 통해 정보를 공유할 때 적합하고 SOAP도 마찬가지로 공개 표준이다.

형식 정확도를 유지한다는 말은 개체를 serialize을 하고 다시 deserialize했을 때 원본의 개체의 정확한 복제본이 만들어 진다는 것을 의미한다.

 

이진 serialization

serialize하고자 하는 개체의 public, private필드 와 클래스 이름을 모두 바이트의 스트림 (Binary)로 변환하는 방식이다. 그 후 개체가 deserialize되면 원본 개체의 정확한 복제본이 만들어진다.

이진 serialization에는 3가지 방법이 있다.

 

기본 serialization

serialize하고자 하는 class Serializable특성으로 표시 하는 것으로 해당 클래스의 모든 부분을 serialize한다.

 

    [Serializable]

    public class MyObject

    {

        public int n1 = 0;

        public int n2 = 0;

        public String str = null;

    }

 

MyObject라는 classSerializable 특성으로 표시하였다.

 

MyObject의 객체를 serialize 하여 파일로 저장하는 예

 

MyObject obj = new MyObject();

obj.n1 = 1;

obj.n2 = 24;

obj.str = "Some String";

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);

formatter.Serialize(stream, obj);

stream.Close();

 

순서를 요약해보면

1.      인스턴스 생성.

2.      BinaryFormatter를 만든다.

3.      파일로 저장하기 위한 FileStream을 만든다.

4.      Formatter에게 stream과 개체를 매개 변수로 제공하고 serialize를 지시한다.

5.      stream을 닫는다.

 

이번에는 반대로 serialize된 개체를 반대로 deserialize로 복원 하는 예

 

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);

MyObject obj = (MyObject)formatter.Deserialize(stream);

stream.Close();

 

1.      BinaryFormatter를 만든다.

2.      저장된 파일을 stream으로 오픈한다.

3.      Formatter에게 stream을 제공하고 Deserialize를 지시하고 개체를 받는다.

 

선택적 serialization

class에서 serialize하지 않아야 하는 필드가 있을 때 해당 멤버변수를 NonSerialized특성으로 표시해 줌으로써 해당 변수가 Serialize되는 것을 방지할 수 있다.

 

    [Serializable]

    public class MyObject

    {

        public int n1 = 0;

        [NonSerialized]

        public int n2 = 0;

        public String str = null;

    }

 

MyObject클래스의 n2 멤버는 더 이상 serialize되지 않는다.

NonSerialized 특성을 적용했을 때와 적용하지 않았을 때 각각 serialize, deserialize하여 비교해보면 n2멤버의 값이 다름을 확인해 볼 수 있다.

결국 NonSerialized로 표시되지 않은 모든 필드는 serialize된다.

 

Custom serialization

Custom serializationserialization을 직접 제어하는 방식이다. Custom serialization에는 2가지 방법이 있는데

첫번째로는 serialization 도중과 이후에 데이터를 수정하는데 사용되는 메서드에 다음 특성을 적용한다.

l  OnDeserializedAttribute

l  OnDeserializingAttribute

l  OnSerializedAttribute

l  OnSerializingAttribute

 

    // This is the object that will be serialized and deserialized.

    [Serializable()]

    public class TestSimpleObject

    {

        // This member is serialized and deserialized with no change.

        public int member1;

 

        // The value of this field is set and reset during and

        // after serialization.

        private string member2;

 

        // This field is not serialized. The OnDeserializedAttribute

        // is used to set the member value after serialization.

        [NonSerialized()]

        public string member3;

 

        // This field is set to null, but populated after deserialization.

        private string member4;

 

        // Constructor for the class.

        public TestSimpleObject()

        {

            member1 = 11;

            member2 = "Hello World!";

            member3 = "This is a nonserialized value";

            member4 = null;

        }

 

        public void Print()

        {

            Console.WriteLine("member1 = '{0}'", member1);

            Console.WriteLine("member2 = '{0}'", member2);

            Console.WriteLine("member3 = '{0}'", member3);

            Console.WriteLine("member4 = '{0}'", member4);

        }

 

        [OnSerializing()]

        internal void OnSerializingMethod(StreamingContext context)

        {

            member2 = "This value went into the data file during serialization.";

        }

 

        [OnSerialized()]

        internal void OnSerializedMethod(StreamingContext context)

        {

            member2 = "This value was reset after serialization.";

        }

 

        [OnDeserializing()]

        internal void OnDeserializingMethod(StreamingContext context)

        {

            member3 = "This value was set during deserialization";

        }

 

        [OnDeserialized()]

        internal void OnDeserializedMethod(StreamingContext context)

        {

            member4 = "This value was set after deserialization.";

        }

    }

 

각 특성을 적용한 메서드에 원하는 동작을 구현하면 된다.

 

두번째로는 해당 개체에 ISerializable인터페이스를 구현하면 된다.

ISerializable인터페이스 구현에는 개체가 deserialize될 때 사용되는 특별한 생성자 및 GetObjectData 메서드가 포함되어 있다.

 

    [Serializable]

    public class MyObject : ISerializable

    {

        public int n1;

        public int n2;

        public String str;

 

        public MyObject()

        {

        }

 

        protected MyObject(SerializationInfo info, StreamingContext context)

        {

            n1 = info.GetInt32("i");

            n2 = info.GetInt32("j");

            str = info.GetString("k");

        }

        [SecurityPermissionAttribute(SecurityAction.Demand,

        SerializationFormatter = true)]

 

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)

        {

            info.AddValue("i", n1);

            info.AddValue("j", n2);

            info.AddValue("k", str);

        }

    }

 

serialization시에는 구현된 GetObjectData메서드가 호출 되는데 이는 SerializationInfo를 직접 채워야 한다. 이름 및 값 쌍으로 serialize될 변수를 추가하며 모든 텍스트를 이름으로 사용할 수 있다. SerializationInfo에 추가되는 멤버 변수를 자유롭게 결정할 수 있다.

dserialization시에는 직접 SerializationInfo StreamingContext를 받는 특수 생성자를 만들어야한다. 이것이 누락 된 상태에서 deserialize하려고 하면 예외를 trow한다.

 

XML SOAP Serialization

XML serialization은 개체의 public 필드와 속성 또는 메서드의 매개변수와 반환 값을 XML스트림으로 serialize한다. XML serialization을 사용하면 저장이나 전송을 위해 직렬형식으로 변환되는 public 속성 및 필드가 있는 강력한 형식의 클래스가 만들어 진다.

XML serialization의 특징

l  XML은 공개 표준이기 때문에 XML 스트림은 플랫폼에 관계없이 필요에 따라 모든 응용 프로그램에서 처리될 수 있다.

l  XML serializationSOAP 사양과 일치하는 XML 스트림으로 개체를 serialize 하는 데 사용할 수도 있다.

l  개체를 serialize하거나 deserialize하기 위해서는 XmlSerializer클래스를 사용한다.

l  serialize된 데이터에는 데이터 자체와 클래스의 구조만 포함된다.

l  public 속성 및 필드만 serialize될 수 있다. 속성에는 public 접근자(get, set)가 있어야 한다. public이 아닌 데이터를 serialize해야 하는 경우 이진 serialization을 사용한다.

l  class에는 XmlSerializer에 의해 serialize될 기본 생성자가 있어야 한다.

l  메서드는 serialize될 수 없다.

 

개체 XML serialize

다음은 개체를 XmlSerializer를 이용하여 serialize한다.

 

    public class MyObject

    {

        public int n1 = 0;

        public int n2 = 0;

        private int n3 = 0;

        public String str = null;

 

        public MyObject()

        {

            n1 = 1;

            n2 = 2;

            n3 = 3;

            str = "Xml Serialization";

        }

    }

   

    class Program

    {

        static void Main(string[] args)

        {

            MyObject myObject = new MyObject();

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));

            StreamWriter writer = new StreamWriter("myObject.xml");

            xmlSerializer.Serialize(writer, myObject);

            writer.Close();

        }

    }

 

1.      serialize하고자 하는 인스턴스 생성

2.      XmlSerializer를 생성자에 serialize하고자 하는 인스턴스의 타입을 전달하여 생성

3.      기록할 stream생성

4.      XmlSerializer에게 stream과 개체를 전달하여 serialize지시

 

위의 결과 물인 myObject.xml에는 다음과 같은 내용이 있다.

 

<?xml version="1.0" encoding="utf-8"?>

<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <n1>1</n1>

  <n2>2</n2>

  <str>Xml Serialization</str>

</MyObject>

 

private 멤버와 메서드의 정보는 기록 되지 않는 것을 확인할 수 있다.

 

개체 XML deserialize

이번에는 myObject.xml을 다시 deserialize해본다.

 

    class Program

    {

        static void Main(string[] args)

        {

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));

            StreamReader reader = new StreamReader("myObject.xml");

            MyObject myObject = (MyObject) xmlSerializer.Deserialize(reader);

 

            Console.WriteLine(myObject.n1);

            Console.WriteLine(myObject.n2);

            Console.WriteLine(myObject.str);

        }

    }

 

1.      XmlSerializer를 생성자에 deserialize하고자 하는 인스턴스의 타입을 전달 하여 생성

2.      stream을 읽어 들이는 reader 생성

3.      XmlSerializer에게 stream을 전달하여 deserialize를 지시하고 리턴되는 Object를 복원하고자 하는 타입에 맞게 캐스팅 하여 받아 낸다.

 

개채를 SOAP 인코딩된 XML 스트림으로 Serialize하기

SOAP 메시지는 XML을 사용하여 생성되므로 XmlSerializer를 사용하여 클래스를 serialize하고 인코딩된 SOAP 메시지를 생성할 수 있다.

SOAP 인코딩된 XML serialize하기 위해서는 기존의 XML serialize에서 XmlSerializer생성자 매개 변수에 serialize 하고자 하는 인스턴스의 타입을 전달 했던 것과 달리, SoapReflectionImporter를 만들고 serialize된 클래스의 형식으로 ImportTypeMapping 메서드를 호출하여 XmlTypeMapping을 만든뒤 XmlSerializer생성자 매개 변수에 전달 한다.

 

    class Program

    {

        static void Main(string[] args)

        {

            MyObject myObject = new MyObject();

 

            XmlTypeMapping xmlTypeMapping =

                      new SoapReflectionImporter().ImportTypeMapping(typeof (MyObject));

 

            XmlSerializer xmlSerializer = new XmlSerializer(xmlTypeMapping);

            StreamWriter writer = new StreamWriter("myObject.xml");

            xmlSerializer.Serialize(writer, myObject);

            writer.Close();

        }

    }

 

기존의 XML serializer에서 XmlSerializer의 생성방식만 변경되었다.

 

이때 결과물 myObject.xml에는 다음과 같은 내용이 있다.

 

<?xml version="1.0" encoding="utf-8"?>

<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1">

  <n1 xsi:type="xsd:int">1</n1>

  <n2 xsi:type="xsd:int">2</n2>

  <str xsi:type="xsd:string">Xml Serialization</str>

</MyObject>

 

SOAP형식으로 인코딩된 데이터가 있음을 확인할 수 있다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License

'Study' 카테고리의 다른 글

.NET(C#) Serialization , Deserialization  (1) 2009/11/30
E-mail 분석기  (0) 2009/10/13
Trackback 0 Comment 1
2009/10/29 19:33

SSH를 이용한 파일 전송 (SCP)

scp [source] [destination]

-p : 포트번호 지정
-r : 하위 디렉토리모두 포함

예)
scp -P 5567 -r talsu@livedevil.net:/home/media/Storage300/APP/Music ./
scp -P 5567 -r ./* talsu@livedevil.net:/home/media/Storage300/APP/Music


수십번을 써도 해깔리네..
이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0