Quantcast
Channel: web pakun
Viewing all 247 articles
Browse latest View live

2016年1月開始の『マイナンバー制度』運用の対応(中小企業)

$
0
0

マイナンバー運用を知る

2016年1月から『マイナンバー制度』の運用が開始されます。
マイナンバー(個人番号)の管理は基本的に会社単位で行う必要がありますが、管理を委託することも可能です。

しかしマイナンバーの取扱いの「基本方針」は、委託の有無に関わらず各社で策定するものです。中小企業(従業員100名以下)は軽減措置が取られていますので最低限の対応のみで間に合わせましょう。実際に運用しながら改善できます。
気を付けたいのは“罰則規程”が厳しくとられることです。これは企業規模に関わらず適用され、その範囲が個人にも及ぶものとなっています。

そのためにも、まずは“知る”ことからです。内閣官房のサイトに詳しい内容と運用の仕方がありますので参考にするのもよいでしょう。
内閣官房サイトマイナンバー制度

マイナンバー管理運用の明確化とポイント

マイナンバー基本方針、取扱規程の策定は中小企業については任意となっていますが、取扱いの責任者(担当者)や実務の流れの明確化は最低限する必要があります。実務のフローと情報管理の責任者、対応引き継ぎ等の確認(明文化)は必ず行いましょう。

対応を行う際の留意点として考えられるのは以下の通りです。(中小企業向け)

  • 事務における責任者の設置及び責任の明確化
  • 事務取扱担当者の明確化及びその役割の明確化
  • 事務取扱担当者が取扱う特定個人情報等(マイナンバー)の範囲の明確化
  • 事務取扱担当者が取扱規程等に違反している事実またはその兆候を把握した場合の責任者への報告連絡体制
  • 情報漏えい等事案の発生または兆候を把握した場合の責任者等への報告連絡体制
  • 特定個人情報等を複数の部署で取扱う場合の各部署の任務分担及び責任の明確化

これらの明文化はもちろん、分かりやすいようにフロー図を作って運用実務のマニュアルを作成するのもよいでしょう。

フロー図

(情報漏えいに関しては以前からある個人情報保護法に準ずる)
※情報漏えいの際に報告を要しないケース

  1. 影響を受ける可能性のある本人すべてに連絡した場合。
  2. 外部に漏えいしていないと判断される場合
  3. 従業員が不正に持ち出したり利用したりした事案ではない場合
  4. 事実関係の調査を了し、再発防止を決定している場合
  5. 事案における特定個人情報の本人の数が100人以下の場合

※101人以上の従業員の事業規模に報告義務があります。

もしもの時のマイナンバーについての問い合わせ先
0120-95-0178/お問い合わせ


簡単!ExcelVBAでつくるマイナンバー管理システム(準備編)

$
0
0

コスト削減!自社内で簡単管理のすすめ

中小企業にはマイナンバーを運用するための「安全管理措置」の軽減が取られていますが、マイナンバー取扱いに関する業務の取扱いの記録を残すことは義務付けられています。いわばマイナンバーに関わる業務の作業報告を記録することです。委託する場合でもその委託の事実を記録する必要があります。
これは①特定個人情報取扱記録台帳を作成して記録すればよいでしょう。

また会社規模に関わらず従業員や給与(報酬)を支払っている関係者のマイナンバーを取得する必要があります。基本的に従業員及びその扶養家族のマイナンバーを取得するのはその会社の事務取扱者しかできません。

所得したマイナンバーの管理を委託することは可能ですが、コストをかけなくても自社で管理することができます。Excelを利用している会社であればExcelVBAを利用した簡単な②運用システムで対応が可能です。
セキュリティと記録をとることを徹底して自社での運用をおすすめします。

ではExcelVBAを利用したマイナンバー運用システムと記録台帳の作成方法をご紹介します。

マイナンバー管理システムの必要性

マイナンバーの管理やセキュリティ対策を行うのはすべての会社にとって義務です。委託すれば簡単だけど、そこまでコストをかけられないというのが本音。
そこで簡単なVBAの記述をするだけの簡易管理システムを作りました。最低限の機能は備えていますが、これを元に自社オリジナルの簡易体制を作ってください。

マイナンバー管理体制のポイント

重要なのはこれまでの情報管理(社員情報、勤怠管理、給与等)システムとは切り離して、マイナンバー単独で管理することです。安全管理措置の面からも情報は分散させたほうが賢明です。
管理システムのポイントとして特に重要なことは3点あります。

  1. マイナンバーは独立して管理する
  2. アクセス権限を決める
  3. 操作・照会ログ(証跡)を残し、分析できるようにする

それでは具体的な管理システムを作成していきます。

必要な環境の設定

  • 必要な環境:管理用の独立した環境(取扱担当者および責任者のみがアクセスできるパソコン及びExcel
  • ファイルの作成:
    ①特定個人情報取扱記録台帳(Excel/人為的入力)
    ②マイナンバー管理システム(ExcelVBA/自動)
  • システム要件:上記、管理体制のポイントの機能を備えている

最低限のセキュリティで必要なのは“アクセス制限をする”ことと、もしもの場合に対応できる“情報(記録)を持つ”ことです。
※パソコンにセキュリティソフトを搭載していることが前提です。

簡単!ExcelVBAでつくるマイナンバー管理システム(実践編Excel)

$
0
0

はじめに、管理システムファイルをどこにおくかを決めます。マイナンバー運営で利用する書類のひな形や取扱規程、マニュアルと同じフォルダにまとめるのがよいでしょう。
■任意の場所に「マイナンバー」運用フォルダを新規で作成する。(フォルダファイルは自由でOK)

1.特定個人情報取扱記録台帳を作る

■「Excelワークシート」を新規作成する。
→フォルダ名は任意で(ここでは「特定個人情報取扱管理台帳」とします)
※手入力です。マイナンバーを利用した【業務内容】を記述します。
【記入項目】
○日付:作業(業務)を行った日付
○種類/名称:作業をした(マイナンバーを使用した)書類、ファイル
○対象者:従業員、扶養家族、取引先、等
○情報の項目:氏名、生年月日、個人番号、等
○利用目的:税務署への提出、新規入社手続き、等
○記録媒体:紙、システム(データベース)、USB
○取扱部署:人事部、経理部
○取扱担当者:アクセス権をもつ人(業務を行う人)
○責任者:総務部長、人事部長、
○保管場所:システム内(PC)、施錠できるキャビネット
○保存期間:必要なくなったとき、3年、7年
○削除・破棄方法:シュレッダー、データ消去

台帳

(台帳イメージ)

2.管理システムをつくる

マイナンバー取扱いのログ(記録)を“自動で”とるものです。作為を加えない、ありのままの情報です。
■新規でExcelファイルを作成する。
–任意でファイル名を付ける(ここでは「マイナンバー管理システム」)
–作成するExcelに“パスワード”の設定を行う。

《パスワードの設定方法》
一旦、作成したファイルを開き「名前を付けて保存」でパスワードの設定を行う。
この時に設定を行う項目は、
-①ファイルの種類の変更(Excel.xlsx→Excelマクロ有効ブック.xlsm
-②バックアップファイルを作成。レ点を付ける。
-③読み取りパスワード/書き込みパスワードの2種類を設定する

パスワードの設定

■新規Excel内に記録用ログ取得シートを4つ、システム利用ログ取得シート(隠しシート)を1つ作成(計5シートを作成)
つくるシートと項目は、
特定個人情報:記入、閲覧等の実務で利用頻度がいちばん高い(項目∥名前、処理、個人番号)
更新記録:①シートの更新が行われた場合、自動でログを取得(項目∥シート名、名前、ユーザー、日時、備考)
開閉履歴:システムへのアクセス記録を取得する(項目∥日時、開閉、ユーザー)
印刷履歴:個人番号情報が出力(プリントアウト)された場合の記録を取得(項目∥日時、印刷、ユーザー)
data:管理システム内の動作に対してログを取得する(項目∥シート名、日、セル、ユーザー)
–“隠しファイル”にします。(隠しファイルにするためには、『dataシート』→右クリック→「非表示」)メンテナンスの時に不正な動きがないかチェックします。

実際に手入力して使用するシートは「特定個人情報」のシートのみです。他はセキュリティの観点から“記録を残す”ことを目的にログが自動で収集されます。
この一連の動作をVBAでシステム化します。

隠しファイル

Salesforceに接続して、オブジェクト加工等を行うEclipseプロジェクトのテンプレート

$
0
0

Salesforceを使った案件をやっていると、通常のバッチ開発とは別に、「こういうことしたい」とか、「こんな情報を取得したい」といった要望が出てくることがよくあります。

対象が数件であれば手動で作業してもいいのですが、件数が多くなるとさすがにプログラムでやったほうが便利ですよね。

Salesforceとプログラムでやり取りするにはいくつかの方法があり、APIと呼ばれます。その主なものとしては、以下の2つがあります。

REST API RESTベースのAPIです。サービス同士を比較的疎に接続でき、開発が容易なため、モバイルアプリやWebアプリからのCallで利用されることが多いと思います。
SOAP API SOAP形式のWebサービスベースのAPIです。SOAP API を使用して、レコードの検索、作成、更新、削除などができます。バッチシステムなどで利用されることが多いと思います。

ここでは、SOAP APIを利用して、Javaで開発を行うプロジェクトのひな形を作ります。

 

WSDLの用意

JavaからWebサービス経由でメソッドを呼びますので、WSDLファイルを用意します。これは、Salesforceの組織にログインして、「ビルド→開発→API」から取得します。いくつか種類がありますが、なるべく1つの組織に依存しないプロジェクトのひな形を作成するために、今回は「Partner WSDL」にしましょう。同ページに説明がありますが、「Enterprise WSDL」が強い型情報をもとに、カスタムオブジェクトのクラスまで生成するのに対して、「Partner WSDL」は比較的柔軟な定義です。

image

では、「パートナーWSDLの生成」をクリックして、「Partner WSDL」をダウンロードして来ましょう。

 

プロジェクトに必要なjarファイルの用意

上記で用意した「Partner WSDL」を 、どこか適当なディレクトリに置きます。(「partner.wsdl」という名前で保存しました。)

次に、「partner.wsdl」と同じディレクトリに、sfdc-wscからダウンロードした「wsc-xx.jar」を置きます。(今回はwsc-23.jar)

2つを配置できたら、コマンドプロンプトを起動し、そのディレクトリに移動して、以下のコマンドを打って実行します。

“C:\Program Files\Java\jdk1.7.0_79\bin\java” -classpath wsc-23.jar com.sforce.ws.tools.wsdlc partner.wsdl partner.jar

すると、「partner.jar」が生成されるはずです。

 

プロジェクトの作成

ここまで来たら、用意はできました。Eclipseで新規Javaプロジェクトを作成してください。

上記の「wsc-XX.jar」と「partner.jar」をclasspathに入れれば、以下のひな形ソースがコンパイルできるはずです。

import com.sforce.soap.partner.Connector;
import com.sforce.soap.partner.DeleteResult;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.SaveResult;
import com.sforce.soap.partner.Error;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

public class Main {
  
  static final String USERNAME = "YOUR-USERNAME";
  static final String PASSWORD = "YOUR-PASSWORD&SECURITY-TOKEN";
  static PartnerConnection connection;

  public static void main(String[] args) {

    ConnectorConfig config = new ConnectorConfig();
    config.setUsername(USERNAME);
    config.setPassword(PASSWORD);
    config.setTraceMessage(true);
    //proxy経由で接続するなら、下記をコメントアウトしてください。
    //config.setProxy("xxxxxxxxxx", 8888);

    try {
      
      connection = Connector.newConnection(config);
      
      // display some current settings
      System.out.println("Auth EndPoint: "+config.getAuthEndpoint());
      System.out.println("Service EndPoint: "+config.getServiceEndpoint());
      System.out.println("Username: "+config.getUsername());
      System.out.println("SessionId: "+config.getSessionId());
      
      queryContacts();
      
    } catch (ConnectionException e1) {
        e1.printStackTrace();
    }  

  }
  
  private static void queryContacts() {
    
    System.out.println("Querying for the 5 newest Contacts...");
    
    try {
       
      QueryResult queryResults = connection.query("SELECT Id, FirstName, LastName, Account.Name " +
              "FROM Contact WHERE AccountId != NULL ORDER BY CreatedDate DESC LIMIT 5");
      if (queryResults.getSize() > 0) {
          for (SObject s: queryResults.getRecords()) {
            System.out.println("Id: " + s.getId() + " " + s.getField("FirstName") + " " + 
                s.getField("LastName") + " - " + s.getChild("Account").getField("Name"));
          }
        }
      
    } catch (Exception e) {
      e.printStackTrace();
    }    
    
  }
  
 
}

 

それでは、次回からは、このひな形を使って、具体的なバッチ加工を行っていきましょう。

 

 

 

参考URL: developer.salesforce.comの「Introduction to the Force.com Web Services Connector」

Salesforceの添付ファイルを移行用にダウンロードする

$
0
0

How can I download attachment files from salesforce by soap api.

notebook-1042595_960_720
 

Salesforce上のあるオブジェクトについている、メモ&添付ファイル(Attachment)をまとめて別の組織に移行したいというときのTipsです。
このようなことを実現するためには、

①Salesforceから添付ファイルをダウンロードする。この際に、移行先のオブジェクトに紐付けられるよう、移行元オブジェクトのIDや名称も同時に取得しておく。

②添付するオブジェクトを、移行先の組織に作成する。

③それらのオブジェクトに添付ファイルをアップロードする。

という手順を踏むことになると思います。

どの添付ファイルがどのオブジェクトに添付されていたかの情報と、実際の添付ファイルがあれば、アップロード自体はDataloaderやプログラムでできますので、今回は「添付されている親のオブジェクトのIdと名称のディレクトリを作成し、そこに添付ファイルをダウンロードする」プログラムをJavaで作成しようと思います。

Eclipseのプロジェクトは、「Salesforceに接続して、オブジェクト加工等を行うEclipseプロジェクトのテンプレート 」を利用すると簡単です。

 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import com.sforce.soap.partner.Connector;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
import com.sforce.ws.bind.XmlObject;
import com.sforce.ws.util.Base64;


public class Main {
  
  static final String USERNAME = "YOUR-USERNAME";
  static final String PASSWORD = "YOUR-PASSWORD&SECURITY-TOKEN";
  static final String OUTPUT_DIR = "C:\\OUTPUT\\";
  //対象のオブジェクトのAPI参照名をセット
  static final String OBJ_TYPE = "Account";
  static PartnerConnection connection;

  public static void main(String[] args) {

    ConnectorConfig config = new ConnectorConfig();
    config.setUsername(USERNAME);
    config.setPassword(PASSWORD);
    //config.setTraceMessage(true);
    //config.setProxy("xxxxxxxxx.co.jp", 8888);

    
    try {
      
      connection = Connector.newConnection(config);
      
      // display some current settings
      System.out.println("Auth EndPoint: "+config.getAuthEndpoint());
      System.out.println("Service EndPoint: "+config.getServiceEndpoint());
      System.out.println("Username: "+config.getUsername());
      System.out.println("SessionId: "+config.getSessionId());
      

      queryAttachments();
      
      
    } catch (ConnectionException e1) {
        e1.printStackTrace();
    }  

  }
  

  private static void queryAttachments() {
       
    try {
    	
      QueryResult queryResults = connection.query("SELECT Id, Name "
      		+ "FROM Attachment "
      		+ "WHERE Parent.Type IN (\'"+ OBJ_TYPE + "\')");
      
      System.out.println(queryResults.getSize());
      
      if (queryResults.getSize() > 0) {
    	  for (int i=0;i<queryResults.getRecords().length;i++) {
    		  
    		  SObject s = (SObject)queryResults.getRecords()[i];
    		  
    		  QueryResult queryAttachResults = connection.query("SELECT Id, Name, Body, "
    		      		+ "BodyLength, ContentType, "
    		      		+ "IsDeleted, Description, OwnerId, IsPrivate, "
    		      		+ "ParentId, Parent.Id, Parent.Name "
    		      		+ "FROM Attachment "
    		      		+ "WHERE Id = \'" + s.getId() + "\'");
    		  
    		  SObject sAttach = (SObject)queryAttachResults.getRecords()[0];
    		  
    		  System.out.println("Id: " + sAttach.getId() + " " + sAttach.getField("Id") + " " + 
    				  sAttach.getField("Name") +  sAttach.getField("ContentType"));
    		  
    		  XmlObject obj = (XmlObject)sAttach.getField("Parent");
    		  System.out.println(obj.getField("Id"));
    		  System.out.println(obj.getField("Name"));

    		  writeAttachments(sAttach, obj);
      	   
    	  }
    	}
      
    } catch (Exception e) {
      e.printStackTrace();
    }    
    
  }
  
  
  private static void writeAttachments(SObject sObject, XmlObject xmlObj) throws IOException{
	  
	    FileOutputStream writer = null;
	 
	    try {
	    	String subdir = OUTPUT_DIR + xmlObj.getField("Id") + "_"+ xmlObj.getField("Name");
	    	File suvdir = new File(subdir);

	    	suvdir.mkdir();

            writer = new FileOutputStream(subdir + "\\" + (String)sObject.getField("Name"));

            String s1= (String)sObject.getField("Body");

            writer.write(Base64.decode(s1.getBytes()));
 
            if (writer != null) {
                writer.close();
            }

	    }catch(Exception e){
	    	e.printStackTrace();
	    	
	    } 
	    finally {
	        if (writer != null) {
	            writer.close();     }
	 
	    }
	}
  
 
}

 

上記のプログラムは、「Account」オブジェクトに添付されているファイルを、「C:\OUTPUT」フォルダ直下に「親オブジェクトのID_親オブジェクトの名称」というフォルダを作成して、そこにダウンロードします。「C:\OUTPUT」ディレクトリは前もって作成しておいてください。(上記のプログラムでディレクトリを変更した場合は、そのディレクトリに読み替えてくださいね。)

また、

If your query returns the Body field, your client application must ensure that only one row with one Attachment is returned; otherwise, an error occurs.

出典: SOAP API Developer’s Guide

の通り、SOQLにBodyを含めると、戻りの件数は1件になってしまうため、一度添付ファイルのIDを取得してから、Bodyを一件ずつ取得するようになっています。

Javaでexcelを読み書きするサンプル(Apache POIの使い方まとめ)

$
0
0

業務用のシステムを構築する際に、結構な頻度で考えなくてはいけないのが、エクセル形式のファイル。

様々な企業で幅広く使用されているため、プログラムから扱う場面も少なくありません。

そこで今回は、Javaを利用してエクセルファイルを読み書きするサンプルを作成しておきます。
(何度も使うので、サクッと使える自分用まとめかな)こういう場合、ApacheのPOIというライブラリを使うと便利ですよねー。

最近のPOIでは、Excel2003形式である「.xls」とExcel2007形式である「.xlsx」の両方のタイプのエクセルファイルを扱うことができます。

そもそも、両形式はどのように異なるのかというと、

    • Excel97形式(拡張子が.xls)

「Microsoft OLE 2複合ドキュメント形式」(OLE2形式)のフォーマット。バイナリ形式で、オープンな規格ではない。

    • Excel2007形式(拡張子が.xlsx)

「Office Open XML形式」(OOXML形式)対応のフォーマット。その名の通り、オープンな規格。OpenOfficeもこの形式に対応している。

という感じになっています。

 

Apache POIも、Ver3.5より、ようやくOOXML形式に対応し、両形式を扱えるようになりました。
なお、その影響で、依存するjarが多くなり、若干分かりにくくなってしまった感は否めないですが。。。

途中から形式が変わってしまったという経緯から、使用するクラス群、パッケージも、それぞれで異なります。
大きくは、

    • HSSF系(org.apache.poi.hssf)

OLE2形式のファイルフォーマットのJava実装

    • XSSF系(org.apache.poi.xssf)

OOXML形式のファイルフォーマットのJava実装

に分かれていますが、

SS系(org.apache.poi.ss)・・・上記の両者を統一的なインターフェースで扱うことができるパッケージ
SXSSF系・・・3.8-beta3から導入された実装で、非常に大きなエクセルファイルを扱うためのJava実装

も存在していますので、利用用途に応じて使い分けることができます。

では最初にライブラリのインストール、その次に、読み込みのサンプル、最後にエクセルファイルの作成のサンプルを作成します。

 

 

ライブラリのダウンロードと設定

最初にPOIをダウンロードしましょう。

ここからダウンロードします。今回は、「POI 3.13」版を使いますので、「Binary Distribution」の「poi-bin-3.13-20150929.zip」としました。

ダウンロードできたら、適当なディレクトリに解凍します。

poi

以下のようなjarファイルが展開されますので、Eclipse等の開発環境でクラスパスに通します。

必要なjarは、直下にできた
・poi-3.13-xxxxxxxx.jar
・poi-ooxml-3.13-xxxxxxxx.jar
・poi-ooxml-schemas-3.13-xxxxxxxx.jar

と、「ooxml-lib」の下に展開された
・xmlbeans-2.6.0.jar
になります。

 

 

エクセルファイルの準備と読み込みのjavaサンプル

では、実際にコーディングしていきましょう。

ここでは、SS系のクラスを使って、xlsとxlsxの2種類のファイルの内容を読み込むサンプルとしましょう。

まず、読み込む対象のエクセルファイルを作成します。

適当なディレクトリに、「sample1.xlsx」と「sample1.xls」を作成し、シートの内容は以下のようにします。

form

日付型や数式も扱えることを確認するために、3列目には日付、4列目には数式「=CONCATENATE(<セル>,”_TEST”)」を定義しました。

 

javaの具体的なソースは以下の通りです。

import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class Main {
	
	//適当なディレクトリに書き換えてください
	static final String INPUT_DIR = "D:\\MyDownload\\output\\";

	public static void main(String[] args) {
	
    	try {
    		
    	    String xlsxFileAddress = INPUT_DIR + "Sample1.xlsx";
    	    
    	    //共通インターフェースを扱える、WorkbookFactoryで読み込む
    	    Workbook wb = WorkbookFactory.create(new FileInputStream(xlsxFileAddress));
    	    
    	    //全セルを表示する
    	    for (Sheet sheet : wb ) {
    	        for (Row row : sheet) {
    	            for (Cell cell : row) {
    	            	System.out.print(getCellValue(cell));
                        System.out.print(" , ");
    	            }
    	            System.out.println();
    	        }
    	    }
          
            wb.close();
    		
    	}catch (Exception e) {
			e.printStackTrace();
		} finally {
			
		}

	}
	
	
	
	private static Object getCellValue(Cell cell) {
		switch (cell.getCellType()) {
		
			case Cell.CELL_TYPE_STRING:
				return cell.getRichStringCellValue().getString();
				
			case Cell.CELL_TYPE_NUMERIC:
				if (DateUtil.isCellDateFormatted(cell)) {
					return cell.getDateCellValue();
				} else {
					return cell.getNumericCellValue();
				}
				
			case Cell.CELL_TYPE_BOOLEAN:
				return cell.getBooleanCellValue();

			case Cell.CELL_TYPE_FORMULA:
				return cell.getCellFormula();

			default:
				return null;

		}

	}

}

各セルは、文字列型や数値型、日付型などの「タイプ」をもっていますので、それらをハンドリングするのが、自作の「getCellValue」メソッドになります。

resukt

上記のような実行結果になるはずです。

 

 

POIでエクセルファイルの作成を行う。

さて次に、エクセルファイルを作成するサンプルを作成していきましょう。

HSSF系、XSSF系はそれぞれWorkbook、Sheet、RowやCellを扱うためのクラスを持っており、それぞれ、

HSSFWorkbook、HSSFSheet、HSSFRow、HSSFCell

XSSFWorkbook、XSSFSheet、XSSFRow、XSSFCell

となっています。ただ、上記にも述べたSS系(org.apache.poi.ss)パッケージを使うと、共通のRow、Cellクラスで扱えるため、変えるのはWorkbookのクラス部分だけですみます。

RowとCellの基本的な概念は以下の図を参考にしてください。

 

rows

 

import java.io.FileOutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class MainWrite {
	
	//適当なディレクトリに書き換えてください
	static final String INPUT_DIR = "D:\\MyDownload\\output\\";

	public static void main(String[] args) {

		try {
			
			//xlsの場合はこちらを有効化
			//Workbook wb = new HSSFWorkbook();
		    //FileOutputStream fileOut = new FileOutputStream("workbook.xls");
		    
			//xlsxの場合はこちらを有効化
		    Workbook wb = new XSSFWorkbook();
		    FileOutputStream fileOut = new FileOutputStream(INPUT_DIR + "sample2.xlsx");
		    
		    String safeName = WorkbookUtil.createSafeSheetName("['aaa's test*?]");
		    Sheet sheet1 = wb.createSheet(safeName);
		    
		    CreationHelper createHelper = wb.getCreationHelper();
		    
		    //Rows(行にあたる)を作る。Rowsは0始まり。
		    Row row = sheet1.createRow((short)0);
		    //cell(列にあたる)を作って、そこに値を入れる。
		    Cell cell = row.createCell(0);
		    cell.setCellValue(1);

		    row.createCell(1).setCellValue(1.2);
		    row.createCell(2).setCellValue(
		         createHelper.createRichTextString("sample string"));
		    row.createCell(3).setCellValue(true);
		    
		    wb.write(fileOut);
		    fileOut.close();

    		
    	}catch (Exception e) {
			e.printStackTrace();
		} finally {
			
		}


	}

}

上記のサンプルでは、WorkbookUtilクラスの「createSafeSheetName」というメソッドを使用してシート名を作成していますが、これは、シートに使用できない文字をスペースに置き換え、安全な文字列を生成するためです。

また、CreationHelperというクラスも使用しています。このクラスは、いくつか、セルにセットする値を簡便に生成するメソッドを持っていますので、利用すると便利です。

Salesforceの本番組織とSandboxで、リフレッシュなしでライセンスの数をそろえるには?

$
0
0

Salesforceでは、ライセンスという概念があり、購入したライセンスの数だけ、ユーザが使用することができます。
また、本番組織と、検証環境の概念に近い、Sandboxという環境があります。

Sandboxは、便利なことに、本番組織の設定をコピーして作成可能で、「リフレッシュ」という機能を使うと、
本番の設定を反映させることもできます。

licence

このリフレッシュを行うと、ライセンスの数も同期させることができますので、たとえば、

「最初に本番のライセンス10個で契約し、Sandboxを作成したが、その後、20個追加した。検証環境でも、30名のユーザがテストしたい」

といった要望には、Sandboxのリフレッシュで対応することができます。

でも、検証環境ですから、いろいろな機能を開発していますので、本番の設定をリフレッシュしたら、その設定や機能が上書きされてしまうので、リフレッシュしたくないという場面のも多いですよね。

 

そのようなときには、「Match Production Licenses」というボタンを使うとSandboxの設定はそのままで、ライセンス数だけを同期することができます。

「Salesforce Summer ’15」でリリースされた機能で、「組織プロファイル」⇒「組織情報」をたどると、「本番ライセンスに一致」というボタンがありますので、これを押下することでライセンス数の同期が可能です。

 

ただし、このボタンは、本番環境とSandboxのバージョンが一致しているときにしか表示されませんので、表示されていない場合は、両者のバージョンが同じでないと思われます。
その場合は、Caseを立ち上げて、Salesforceのサポートにお願いすればすぐに反映してくれますよ。

指定された文字コードでCSVファイルを出力するjavaサンプル(エスケープ付)

$
0
0

CSVファイルの出力をjavaで行うサンプルです。

ただ、ひとくちにCSVの出力といっても、その要求は様々です。

基本的には、CSVですから、カンマで区切られたファイル形式なわけですが、データとデータの間を「”」(ダブルクォーテーション)で囲むかどうか、また、その場合、データの中にダブルクォーテーションが合った場合はエスケープ処理しないといけないですよね。

CSVファイル出力はいろんなプロジェクトで同じようなことを何度もやるのですが、そのたびにこうったことを考えてクラスを作成するのも手間なので、ここにおいておこうと思います。

 

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class CSVFileWriter {
	
	public static final String RETURN_CODE = "\r\n";
	
	/** エンコード utf8 */
	//public static final String CHAR_CODE = "UTF-8";

	/** エンコード ms932 */
	public static final String CHAR_CODE = "ms932";

	/** 出力ファイル */
	private File outputFile = null;

	/** OutputStream */
	private BufferedOutputStream out = null;

	/** 出力バイト数 */
	private int writeBytes = 0;

	/**
	 * コンストラクタ
	 * 
	 * @param outputFile CSVファイル
	 */
	public CSVFileWriter(final File outputFile) {
		this.outputFile = outputFile;
	}

	/**
	 * ファイルをオープンし、ヘッダ行を読み取ります
	 * 
	 * @throws IOException 入出力例外
	 */
	public final void open() throws IOException {
		close();

		out = new BufferedOutputStream(new FileOutputStream(outputFile));
	}

	/**
	 * ファイルをクローズします.
	 * 
	 */
	public final void close() {
		if (out != null) {
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				out = null;
			}
		}
		writeBytes = 0;
	}

	
	/**
	 * エスケープ処理
	 * 文字列全体を"(ダブルクォーテーション)で囲む
	 * 
	 * @param value カラム値
	 * @return 処理後カラム値
	 */
	private String escape(final String value) {
		if (value == null) {
			return "\"\"";
		}
		
		String ret = value.replaceAll("\"", "\"\"");
		return "\"" + ret + "\"";
	}

	/**
	 * ファイルの出力
	 * 
	 * @throws IOException ファイルの出力に失敗した場合
	 */
	public void flush() throws IOException {
		out.flush();
	}

	/**
	 * 出力バイト数の取得
	 * 
	 */
	public int getWriteBytes() {
		return writeBytes;
	}
	
	
	/**
	 * ファイル出力処理
	 * 
	 * @param line 出力レコード
	 * @throws IOException 入出力例外
	 */
	public void writeLine(final List line) throws IOException {
		StringBuffer sb = new StringBuffer();

		boolean b = false;
		for (String s : line) {
			if (b) {
				sb.append(',');
			}
			sb.append(escape(s));
			b = true;
		}
		sb.append(RETURN_CODE);
		String p = sb.toString();

		byte[] bb = p.getBytes(CHAR_CODE);
		
		out.write(bb);

		writeBytes += bb.length;
	}
	
	/**
	 * ファイル出力処理
	 * 
	 * @param line 出力レコード
	 * @throws IOException 入出力例外
	 */
	public void writeLineWithoutEscape(final List line) throws IOException {
		StringBuffer sb = new StringBuffer();

		boolean b = false;
		for (String s : line) {
			if (b) {
				sb.append(',');
			}
			sb.append(s);
			b = true;
		}
		sb.append(RETURN_CODE);
		String p = sb.toString();

		byte[] bb = p.getBytes(CHAR_CODE);
		
		out.write(bb);

		writeBytes += bb.length;
	}

}

 

これを使うときには、こんな感じで。

 

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;


public class MainCSV {

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


		ArrayList<ArrayList> gLineList = new ArrayList<ArrayList>();
		
		ArrayList lineList = new ArrayList(); 
		lineList.add("col1");
		lineList.add("col2");
		lineList.add("col3");
		lineList.add("col4");
		gLineList.add(lineList);
		
		lineList = new ArrayList(); 
		lineList.add("val1");
		lineList.add("val2");
		//カンマがある場合
		lineList.add("val,3");
		//ダブルクォーテーションがある場合
		lineList.add("val\"4");
		gLineList.add(lineList);
		
		
		CSVFileWriter writer = null;
				
		try {
			File csvFile = new File("D:\\MyDownload\\out.csv");
			
			writer = new CSVFileWriter(csvFile);
			writer.open();
			
			Iterator<ArrayList> iter = gLineList.iterator();
			while(iter.hasNext()){
				writer.writeLine(iter.next());
			}
		}catch(Exception e){
			e.printStackTrace();
			
		} finally {
			// CSVファイルwriterのクローズ処理
			if (writer != null) {
				writer.close();
			}

		}


	}

}

writeLineメソッドを使えばこんな風に出力され、

csv

 

writeLineWithoutEscapeメソッドを使えばこんな風に出力されます。

csv2


Salesforceの標準、カスタムオブジェクトの項目定義書を作成するjavaサンプル

$
0
0

Salesforceでは、Webで簡単に項目を追加したり、項目の属性を変更したりすることができ、非常にスピーディーな開発を行うことができます。

ただ、その項目名や属性を設計書に起こすのは、結構手間だったりします。。。

ツールを使うのもいいですし、javaであれば、自分の好きな項目を好きな形にフォーマットして出力するのも比較的簡単にできます。

ここでは、以前の記事で作成したテンプレートを使って、オブジェクトの項目定義をCSVに出力するプログラムを作成してみましょう。

csvであれば、出力結果をエクセルに貼り付けるのも簡単です。

なお、csv出力には、以前の記事で作成した、「CSVFileWriter」クラスを使っていますので、そちらも参照してください。

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.sforce.soap.partner.Connector;
import com.sforce.soap.partner.DescribeGlobalResult;
import com.sforce.soap.partner.DescribeSObjectResult;
import com.sforce.soap.partner.Field;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.PicklistEntry;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;


public class MainPrefix {
	  
	  //static final String USERNAME = "YOUR-USERNAME";
	  //static final String PASSWORD = "YOUR-PASSWORD&SECURITY-TOKEN";
	  static final String OUTPUT_DIR = "D:\\OUTPUT\\";
	  static PartnerConnection connection;
	  
	  static private List<ArrayList> gLineList = null;

	  public static void main(String[] args) {

	    ConnectorConfig config = new ConnectorConfig();
	    config.setUsername(USERNAME);
	    config.setPassword(PASSWORD);
	    //config.setTraceMessage(true);
	    //config.setProxy("xxxxxx.xxxxx.xx.xx", 8000);

	    
	    try {
	      
	      connection = Connector.newConnection(config);
	      
	      // display some current settings
	      System.out.println("Auth EndPoint: "+config.getAuthEndpoint());
	      System.out.println("Service EndPoint: "+config.getServiceEndpoint());
	      System.out.println("Username: "+config.getUsername());
	      System.out.println("SessionId: "+config.getSessionId());

	      queryAttachments();      
	      
	    } catch (ConnectionException e1) {
	        e1.printStackTrace();
	    }  

	  }
	  

	  private static void queryAttachments() {
	       
	    try {
	    	
	    	DescribeGlobalResult dgr = connection.describeGlobal();
	    	
	    	for (int i = 0; i < dgr.getSobjects().length; i++) {
	    		
	    		System.out.println(dgr.getSobjects()[i].getName());
	    		System.out.println(dgr.getSobjects()[i].getLabel());
	    		System.out.println(dgr.getSobjects()[i].getKeyPrefix());
	    		
	    		//オブジェクトをAccountに制限してます。ここを変更すれば、他のオブジェクトを出力したりできます。
	    		if(dgr.getSobjects()[i].getName().equals("Account")){
	    			writeSObjectDesc(dgr.getSobjects()[i].getName());
	    		}

			}
	      
	    } catch (Exception e) {
	      e.printStackTrace();
	    }    
	    
	  }
	  
	  
	  private static void writeSObjectDesc(String objectName) throws IOException, ConnectionException {
	    	
	    	gLineList = new ArrayList<ArrayList>();
	    	
	    	
			ArrayList lineList = null;
			
			
	    	String objectToDescribe = objectName;
			
			DescribeSObjectResult[] dsrArray = connection.describeSObjects(new String[] { objectToDescribe });
			DescribeSObjectResult dsr = dsrArray[0];

			System.out.println("Object Name: " + dsr.getName());
			lineList = new ArrayList();
			lineList.add("オブジェクト名"); lineList.add(dsr.getName());
			gLineList.add(lineList);
			
			lineList = new ArrayList();
			lineList.add("表示ラベル(日本語)"); 
			if (dsr.getLabel() != null)
				System.out.println("Label: " + dsr.getLabel());
			lineList.add(dsr.getLabel());
			gLineList.add(lineList);
			
			lineList = new ArrayList();
			lineList.add("表示ラベル(英語)"); lineList.add("");
			gLineList.add(lineList);
			
			lineList = new ArrayList();
			lineList.add("カスタムオブジェクトかどうか"); 
			if (dsr.isCustom()){
				System.out.println("Custom Object");
				lineList.add("TRUE");
			}else{
				System.out.println("Standard Object");
				lineList.add("FALSE");
			}
			gLineList.add(lineList);
			
			lineList = new ArrayList();
			lineList.add(""); lineList.add("");
			gLineList.add(lineList);
			
			lineList = new ArrayList();
			lineList.add("項目"); lineList.add("");
			gLineList.add(lineList);
			
			//ヘッダ項目
			lineList = new ArrayList();
			lineList.add("標準項目/カスタム項目");
			lineList.add("項目名");
			lineList.add("表示ラベル");
			lineList.add("必須");
			lineList.add("データ型");
			lineList.add("データ長");
			lineList.add("参照先");
			lineList.add("式");
			lineList.add("ピックリスト項目");
			gLineList.add(lineList);
			

			System.out.println("Number of fields: " + dsr.getFields().length);
			// Now, retrieve metadata for each field
			for (int i = 0; i < dsr.getFields().length; i++) {
				
				
				System.out.println("Field No = ." + i);
				
				// Get the field
				Field field = dsr.getFields()[i];
				
				lineList = new ArrayList();
				//カスタム項目かどうか
				if (field.isCustom())
					System.out.println("\tThis is a custom field.");
				if (field.isCustom()){
					System.out.println("Custom field");
					lineList.add("カスタム項目");
				}else{
					System.out.println("Standard field");
					lineList.add("標準項目");
				}
				
				//項目名
				System.out.println("Field name: " + field.getName());
				lineList.add(field.getName());
				
				//表示ラベル
				System.out.println("\tField Label: " + field.getLabel());
				lineList.add(field.getLabel());
				
				//必須
				if (field.isNillable()){
					System.out.println("\tCan be nulled.");
					lineList.add("");
				}else{
					System.out.println("\tCan be required.");
					lineList.add("必須");
				}
							
				//データ型
				System.out.println("\tType is: " + field.getType());
				if (field.getCalculatedFormula()!=null ){
					//nullでなければ数式が入っているということ
					if(field.getType().toString().equals("double")){
						lineList.add("数式 (数値)");
					}else if(field.getType().toString().equals("string")){
						lineList.add("数式 (テキスト)");
					}else{
						lineList.add("想定外の数式");
					}
					
					
				}else{
					lineList.add(field.getType().toString());
				}
				
				
				//データ長
				if (field.getLength() >= 0)
					System.out.println("\tLength: " + field.getLength());
				if (field.getScale() >= 0)
					System.out.println("\tScale: " + field.getScale());
				if (field.getPrecision() >= 0)
					System.out.println("\tPrecision: " + field.getPrecision());
				if (field.getDigits() >= 0)
					System.out.println("\tDigits: " + field.getDigits());
				
				if (field.getType().toString().equals("string") ||
						field.getType().toString().equals("textarea") ||
						field.getType().toString().equals("picklist") ||
						field.getType().toString().equals("id")||
						field.getType().toString().equals("email")) {
					lineList.add(""+ field.getLength());
				}else if(field.getType().toString().equals("percent")||
						field.getType().toString().equals("double")||
						field.getType().toString().equals("currency")){
					lineList.add("("+ (field.getPrecision()-field.getScale()) + ":" +field.getScale() + ")");
				}else{	
					lineList.add(""+ field.getPrecision());
				}
				
				//参照先
				if (field.getType().toString().equals("reference")) {
					System.out.println("\tCan reference these objects:");
					StringBuffer sb1 = new StringBuffer("");
					for (int j = 0; j < field.getReferenceTo().length; j++) { System.out.println("\t\t" + field.getReferenceTo()[j]); sb1.append("参照->" + field.getReferenceTo()[j] + "/");
					}
					lineList.add(sb1.toString());
				}else{
					lineList.add("");
				}
				
				//式
				System.out.println("数式=" + field.getCalculatedFormula());
				if (field.getCalculatedFormula()!=null ){
					lineList.add(field.getCalculatedFormula());
				}else{
					lineList.add("");
				}
				
				//ピックリスト
				if (field.getType().toString().equals("picklist")) {
					System.out.println("\t\tPicklist values: ");
					PicklistEntry[] picklistValues = field.getPicklistValues();
					StringBuffer sb2 = new StringBuffer("");
					for (int j = 0; j < field.getPicklistValues().length; j++) {
						System.out.println("\t\tValue: " + picklistValues[j].getValue());
						sb2.append(picklistValues[j].getValue() + "/");
					}
					lineList.add(sb2.toString());
				}else{
					lineList.add("");
				}
				
				gLineList.add(lineList);
				
				if (field.isNameField())
					System.out.println("\tThis is a name field.");
				if (field.isRestrictedPicklist())
				System.out.println("This is a RESTRICTED picklist field.");

			}

			writeCSVFile(gLineList, objectName);
			
	    }
	    
	    
	    private static void writeCSVFile(List<ArrayList> gLineList, String objectName) throws IOException{

			File csvFile = null;
			CSVFileWriter writer = null;
			
			try {

				csvFile = new File(OUTPUT_DIR + objectName + ".csv");
				writer = new CSVFileWriter(csvFile);
				writer.open();

				Iterator<ArrayList> iter = gLineList.iterator();
				while(iter.hasNext()){
					
					writer.writeLine(iter.next());
				}
				

			} finally {

				if (writer != null) {
					writer.close();
				}

			}

	    }
	    
	}


出力した結果は、こんな風に出力されます。

csv3

サンプルでは、出力する対象のオブジェクトを「Account」だけに制限しています。(67行目)

ここは、制限を解除したり、出力の必要なオブジェクトのリストを渡すように修正すれば、必要なオブジェクトの項目定義を出力可能ですので、お好きに変更してみてください。

バージョンアップを伴うWrodpressサイトの移行手順

$
0
0

別のVPSサイトでWordpressサイトを運営していましたが、さくらVPSのSSDオプションを使用したくて、移行を行うことにしました。

旧サイトはPHPのバージョンが古かったため、Wordpressのバージョンも古いままにせざるをえなかったのですが、今回はPHPのバージョンもあげられるので、Wordpressのバージョンも一気に4.4.1に変更することにします。

移行の方法として、DBの中身をエクスポートし、そのまま新サイトのWordpressのDBにインポートする方法もありますが、Wordpressのバージョンが変わると、DBの構造も細かい部分で変わっていたり、DBデータには、旧サイトで試したプラグインの、不要なデータも残っていそうなので、DBをまるごとエクスポートするのではなく、記事をエクスポートして、それを新サイトにインポートする方式にしようと思います。

 

手順は以下の通りです。

  • 旧サイトから記事をエクスポート
  • 旧サイトのメディアデータをバックアップ
  • 記事を新サイトにインポート
  • 画像ファイルのアップロード

 

旧サイトから記事をエクスポート

始めに、移行対象の記事をエクスポートしておきます。

WordPressの管理画面で、「ツール」⇒「エクスポート」を選択します。

「エクスポートする内容を選択」しますが、これは「すべてのコンテンツ」を選択すると、記事だけでなく、カテゴリやタグも一緒に移行できますので、便利だと思います。

WS000000

 

「エクスポートファイルをダウンロード」ボタンを押下すると、対象のファイルがXML形式でダウンロードされますので、ローカルのPCの適当なディレクトリに置いておきましょう。

 

旧サイトのメディアデータをバックアップ

旧サイトで記事に使っていた画像ファイルをローカルPCにダウンロードしておきます。

WinSCPなどのソフトでWordpressをインストールしていたディレクトリの「wp-content」配下の「uploads」ディレクトリをそのままの構造でダウンロードしましょう。(WordPressはこのディレクトリにアップロードしたファイルを置きます。)

 

記事を新サイトにインポート

さて、いよいよダウンロードしたxml形式の記事を新サイトにインポートします。

今回の移行では、旧サイトでブックマークしてくれたユーザさんのリンク等はそのままにしておきたいので「同じドメイン,URLをする」という前提があります。

そのため、旧サイトから必要なデータをダウンロードしたら、新しいサイトにも同じURLでアクセスするため、Windowsであれば、「hosts」ファイルを書き換え、新サイトのドメインとIPアドレスをマッピングさせておきます。

また、インポートには、Wordpressで「インポートツール」プラグインが有効になっている必要があります。インストールして、有効化しておきましょう。

WS000001

有効化を確認できたら、インポート作業に入ります。

「ツール」⇒「インポート」をクリックします。すると、インポート元のシステムを選択できる画面に行きます。旧サイトもWordpressですので、「Wordpress」を選択しましょう。

ここで、先ほどダウンロードしたファイルをアップロードすればいいのですが、選択する前に、アップロードできるファイルの最大サイズを確認しておきましょう。多くの場合、デフォルトで2Mとなっています。記事数が多いと、簡単に2M超えてしまうので、移行対象の記事がアップロードできるサイズまで大きくしておきます。

import2

さて、最大サイズを増やして、「ファイルをアップロードしてインポート」ボタンを押下すると、以下のような画面になります。

import3

「Import Attachments」オプションにチェックを入れると、添付ファイルをダウンロードしてインポートしてくれますが、今回は手動で画像ファイルをダウンロードするので、チェックは外しておきます。

アップロードが終われば、記事のインポートが完了です。

 

画像ファイルのアップロード

ただ、このままでは、記事中の画像ファイルがリンク切れになってしまいますので、画像をアップロードします。アップロード前に、一回、画像ファイルをアップロードしておくと、適切な権限でUploadsディレクトリが作成されますので、簡単です。

 

まとめ

以上が、Wordpressのバージョンが古い旧サイトから、最新の新サイトに移行するのに私が行った手順です。

今回はドメイン名やURLも変更しないという目的もあったのですが、特に問題なく移行できました。

 

さくら(sakura)のSSD利用vps 契約後の初期設定①

$
0
0

vpsとはVirtual Private Serverの略で、一台のマシンを複数人で共有しながらも、仮想的には個人的なサーバとして利用できるようにしたものです。

僕らがサーバを契約する際には、その他に、共有サーバや専用サーバ等の選択肢がありますが、vpsは共用サーバよりは自由度の高い環境を、専用サーバより安い値段で利用できる、中間的な位置づけとなります。

例えば、共用サーバでは設定が他の人と共用になってしまうため、ひとつのWordPressで複数のサイトを運営する「マルチサイト」など、WordPressやMySqlの構成の変更を伴うような設定を行うことは、基本的に難しいですよね。

その点、vpsであれば、比較的自由に変更できます。

さくらvpsとはさくらインターネット株式会社が提供しているvpsサービスです。

vpsも、サービス内容は各社微妙に異なりますが、さくらvpsは、比較的シンプルな構成で自由度が高く、ハードウェアのスペックも良いと思います。

特に、SSDとHDDを選択できるプランをいち早く導入したため、SSDを利用して、レスポンスの良いサイト構築を試してみることも可能です。※SSDを使うと、DBへの書き込みやファイル読み込みなど、ディスクIOというところが早くなるので、ページを開いてから表示されるまでの時間が短くなり、その結果、レスポンスもよくなります。

2週間無料のお試し期間もあるようですので、使い勝手やレスポンスを確認してから使いたいという人にも親切ですね。

この一連の記事では、さくらのvpsサーバ契約後、初期設定としてやらなければならないことと、その後、Webサーバを立ち上げて、複数のドメインで複数のWordpressサイトを運営するまでの手順を記述したいと思います。

今回は、以下のことを行って行きますよー。

  • VPSサーバの起動
  • ターミナルソフトをインストールして、VPSサーバにログインできるようにする
  • Teratermのインストールとrootパスワードの変更
  • 一般ユーザの追加
  • システムのアップデート
  • 日本語化
  • sshでのログインを公開鍵暗号方式に変更する
  • sshの設定を変更する
  • iptablesの設定

 

申し込みから最初の一歩 (VPSサーバの起動)

申し込みを行って、(仮)登録のメールをもらったら、最初に何をすればいいでしょうか。

初期状態では、VPSサーバがまだ動いていないので、最初にサーバの起動を行います。

(仮)登録のメールの中に、VPSコントロールパネルのURLとログイン情報が書いてありますので、VPSコントロールパネルにログインします。下記のように、サーバの状態が「停止中」となっているので、「起動」ボタンを押してください。
imageimage

 

状態が「稼働中」になれば、VPSサーバが動き出しています。

 

ターミナルソフトをインストールして、VPSサーバにログインできるようにする。

次の段階ではサーバに「ssh」でログインして、各種設定を行い、サイト運営を行う準備をしていきましょう。

sshとは「Secure Shell/セキュアシェル」のことで、VPSサーバに暗号化技術で安全に接続し、サーバに対して「コマンド」を打ち込むことで、いろいろなことを行えます。

sshでのログインには、Teratermやputtyなどのターミナル・ソフトを使います。どのソフトにも長所がありますが、ここではTeratermを使って説明しますね。

 

Teratermのインストールとrootパスワードの変更

始めに、Teratermのサイトに行きます。

image

サイトに行ったら、ダウンロードリストからファイルをダウンロードします。

今回は「teraterm-4.8.9.exe」をダウンロードし、保存しました。

インストールは保存したファイルをダブルクリックし、「OK」ボタンを押していくだけです。インストールが終わったらさっそく起動してみましょう。

ログインに必要な情報

IPアドレス 「[さくらのVPS] (仮)登録完了のお知らせ」のメールに記載されている[サーバ基本情報]のIPアドレス
ユーザ名 root
パスワード 「[さくらのVPS] (仮)登録完了のお知らせ」のメールに記載されている[管理用ユーザ]の初期パスワード
TCPポート 22番

 

「新しい接続」を設定するダイアログが開きますので、「ホスト」の欄にメールで来ていた、 [サーバ基本情報]のIPアドレス(xxx.xxx.xxx.xxx形式)を入力します。

TCPポートは初期設定なので、「22」のままです。

image

初回ログイン時には、以下のようなエラーが出る場合がありますが、「続行」ボタンを押して次の画面に行ってOKです。

image

次に、SSH認証画面がでますので、ユーザ名「root」とパスフレーズを入力し、「OK」を押します。

パスフレーズ(パスワード)は、(仮)登録メールの中に、「管理用ユーザ」の「初期パスワード」として書いてあります。

その名の通り、rootユーザは管理ユーザとして特権を持っていますので、VPSサーバ内では「神」です。そのパスワードを悪い人に知られてしまうと、あなたのサーバを使って悪いことをされてしまう危険性がありますので、最初のログイン確認後、rootのパスワードは変更し、以後厳重に保管しておきましょう。

image

ログインに成功すると、以下のような画面になります。

image

rootのパスワードを変更するVPSサーバにログインできるようになって最初にするのはrootのパスワード変更です。

 

#passwd

image

 

「New password:」と表示後、希望のパスワードを入力します。入力するパスワードは、表示されません。

「Retype new password:」と表示後、再度、希望のパスワードを入力します。

 

image

 

変更したパスワードを使用して、ログインができるか、確認しておきましょう。

#exit

をタイプしてターミナルを抜け、rootで再度ログインしましょう。

 

ログインに必要な情報

IPアドレス 「[さくらのVPS] (仮)登録完了のお知らせ」のメールに記載されている[サーバ基本情報]のIPアドレス
ユーザ名 root
パスワード 新しいパスワード
TCPポート 22番

 

ログインができれば「rootのパスワード変更」は完了です。

image

 

一般ユーザの追加

rootは非常に権限の強いユーザですので、権限の制限された一般ユーザを作成し、通常の業務ではそちらを使うのが一般的です。それでは早速一般ユーザを作成しましょう。root権限を持つユーザで作業を行ってください。※下記は「myuser」という一般ユーザを作成した例です。ユーザ名はみなさんの環境に合わせて、適宜変更してください。

#ユーザを追加
$ useradd myuser

 

これでユーザが追加されましたが、まだパスワードが設定されていません。

下記コマンドでユーザ「myuser」にパスワードを設定しましょう。

 

#ユーザにパスワードを設定
$ passwd myuser

 

「New password:」と表示後、希望のパスワードを入力します。※入力するパスワードは、表示されません。

「Retype new password:」と表示後、再度、希望のパスワードを入力します。※入力するパスワードは、表示されません。

「all authentication tokens updated successfully.」と表示されればパスワードの変更は完了です。

 

sudoの設定一般ユーザで作業している最中、サーバの設定変更等でroot権限が必要な場合があります。

そんな時にroot権限でコマンドを実行できるsudoを設定しておきましょう。

さくらVPSのデフォルトOSであるCentOSでは通常「wheel」というグループに所属する一般ユーザに対して「sudo」を利用できるように設定します。

root権限を持つユーザで作業を行ってください。<先ほど作成した一般ユーザ「myuser」をグループ「wheel」に設定します。※下記は「myuser」という一般ユーザを作成した例です。ユーザ名はみなさんの環境に合わせて、適宜変更してください。

 

#wheelグループにユーザを追加
$ usermod -G wheel myuser
#追加されているか確認。グループに「wheel」があればOK。
$ id myuser
uid=502(myuser) gid=502(myuser) 所属グループ=502(myuser),10(wheel)

 

初期状態では、「wheel」グループのユーザはsudoできる設定ではありませんので、設定を変更しましょう。

sudo の設定ファイルは「/etc/sudoers」ですが、このファイルを直接編集してはいけません。visudo というファイル編集用のコマンドがあるので、それを使いましょう。

#sudo用ファイルを編集
$ visudo

上記コマンドを入力するとエディタが起動してsudoersファイルが編集状態になります。

キーボードの矢印ボタン(または「j」「k」ボタン)で上下移動できますので、ファイルの下の方に移動し、下記のように修正します。(「# %wheel ALL=(ALL) ALL 」の行まで移動し、「#」にカーソルを合わせて「x」を押すと文字が消えます。2回押して、「%」が先頭になるようにしましょう。)

 

## Allows people in group wheel to run all commands  # %wheel ALL=(ALL) ALL  ↓
## Allows people in group wheel to run all commands  %wheel ALL=(ALL) ALL

 

sudoコマンドを利用できるか、確認してみましょう。一般ユーザでログインし、以下のコマンドを入力します。

 

#sudo情報を表示
$ sudo -l

 

「[sudo] passwrod for ~」と表示されますので、ログインしている一般ユーザのパスワードを入力します。

 

image

 

システムのアップデート

root権限を持つユーザで作業を行います。

 

$ yum update

image

 

 

日本語化

$ vi /etc/sysconfig/i18n

上記コマンド入力後、以下のように変更します。

 

LANG="C"
SYSFONT="latarcyrheb-sun16"
↓
LANG="ja_JP.UTF-8"
SYSFONT="latarcyrheb-sun16"

 

sshでのログインを公開鍵暗号方式に変更する

ターミナルソフトでのログインは当初、ユーザ名とパスワードを入力する方式ですが、パスワードが知られてしまうと誰でもログインできてしまいます。

「パスワードなんて人には教えないよ」と思う人もいるかもしれませが、近年は、VPSサーバに対するブルートフォース攻撃が増えています。これは、サーバのsshポートに対してパスワードの総当たりを行うことでログインできるパスワードを見つけ、サーバを乗っ取ってしまう攻撃です。

そこで、パスワードでログインするのではなく、公開鍵に対応した秘密鍵を使ってログインする方式に変更します。始めに、Teratermを使って、公開鍵と秘密鍵を作成しましょう。いったんTeratermを起動して、「キャンセル」ボタンを押します。

 

image

 

その後、「設定」→「SSH鍵生成」を選択します。

 

image

 

その後表示されるダイアログの「鍵の種類」で「RSA」を選択し、「生成」ボタンを押します。

image

 

鍵が生成されたら、パスフレーズを入力して、公開鍵と秘密鍵を自分のPCに保存します。デフォルトで以下の名前になります。

公開鍵 id_rsa.pub
秘密鍵 id_rsa

 

image

 

保存できたら、Teratermを一旦終了します。再度、Teratermを起動し、公開鍵暗号方式でログインさせたいユーザで、ログインします。ログインできたら、公開鍵(id_rsa.pub)を、Teratermにドラッグ&ドロップします。

 

image

 

ファイル転送を行いますか?というダイアログが表示されますので、「SCP」を押して転送を行います。これによりこのユーザのホームディレクトリに「id_rsa.pub」が配置されました。

 

image

 

これから、公開鍵認証の設定を行います。

 

#「.ssh」ディレクトリを作成する。
$ mkdir .ssh

#「.ssh」ディレクトリの権限を変更する。
$ chmod 700 .ssh

#id_rsa.pubの内容を.ssh/authorized_keysに書き込む。
$ cat id_rsa.pub > .ssh/authorized_keys

#.ssh/authorized_keysの権限を変更する。
$ chmod 600 .ssh/authorized_keys

#id_rsa.pubファイルを消す。
$ rm -f id_rsa.pub

 

sshの設定を変更する

上記のブルートフォース攻撃は、通常のsshポート22番に対してrootユーザで行われます。そのため、ポートの番号を変更し、rootでのログインを禁止します。また、パスワードでのログインも禁止し、公開鍵でのログインを行うようにします。

 

#sshの設定ファイルを編集する。
$ sudo vi /etc/ssh/sshd_config

「#Port 22」の行の「#」を削除し、設定を有効化します。また、「22」を1024~65535の間の数字に変更します。下記はポート番号「10022」を指定した例ですので、みなさんは、ご自分で決めた番号を設定してください。

#Port 22
↓
Port 10022

「#PermitRootLogin yes」の行の「#」を削除し、設定を有効化します。「yes」を「no」に変更します。

これにより、rootでのログインを禁止します。

#PermitRootLogin yes
↓
PermitRootLogin no

「yes」を「no」に変更します。

これにより、パスワードでのログインを禁止します。

PasswordAuthentication yes
↓
PasswordAuthentication no

変更が終わったら「:wq」を入力して保存します。

その後、下記コマンドでsshを再起動します。

 

#sshを再起動する。
$ sudo /etc/init.d/sshd restart

 

それでは、設定した結果が反映されているか、実際に公開鍵方式でログインしてみましょう。Teratermを起動し、

 

IPアドレス 「[さくらのVPS] (仮)登録完了のお知らせ」のメールに記載されている[サーバ基本情報]のIPアドレス
TCPポート sshの設定ファイルに設定したポート番号

image

 

OKボタンを押すと、下記のようなダイアログが表示されます。

ユーザ名とパスフレーズを入力します。

 

ユーザ名 公開鍵を設定した一般ユーザ
パスフレーズ 鍵保存時に設定したパスフレーズ

 

また、保存している秘密鍵を使用しますので、「RSA/DSA/ECDSA/ED25519鍵を使う」をチェックし、秘密鍵(id_rsa)を設定します。

 

image

 

OKを押して、ログイン出来たら成功です。

 

 

iptablesの設定

この記事の最後の作業です。
iptablesの設定を変更します。iptablesは、サーバで受け付けるポート番号を指定したり、ルーティングを行ったりします。不要なサーバへの要求を受け付けなかったり、不審な要求を無視することで、サーバのセキュリティの強化につながります。最近、主に海外から、サーバをのっとるための不審なアタックが多くなっていますので、必ず対応しておきましょう。

#iptablesの設定ファイルを編集する。
$ sudo vi /etc/sysconfig/iptables
*filter
# 外からの通信(INPUT, FORWARD)をすべてDROPする
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
# 中から外へ出ていく通信はすべて通す
:OUTPUT ACCEPT [0:0]
# 確立済みの通信を許可
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# データを持たないパケットの接続を破棄
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
# SYNflood攻撃と思われる接続を破棄
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
# ステルススキャンと思われる接続を破棄
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
# localhostからの通信を許可
-A INPUT -i lo -j ACCEPT
# pingを許可
-A INPUT -p icmp -j ACCEPT

# これ以降は、通したいサービスのポートを書いていく
# SSH  10022は、変更したSSHのポート番号に変更してください
-A INPUT -p tcp -m tcp --dport 10022 -j ACCEPT
# Webサーバ
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
# Webサーバ(SSL)
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# SMTP
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
# SMTP(SSL)
-A INPUT -p tcp -m tcp --dport 465 -j ACCEPT
# POP3
-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
# POP3(SSL)
-A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
# IMAP
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
# IMAP(SSL)
-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
# Tomcat
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT 
COMMIT

#iptablesを再起動する。
$ sudo /etc/rc.d/init.d/iptables restart

さくら(sakura)のSSD利用vps 契約後の設定②(複数WordPressサイトの立ち上げ)

$
0
0

前回までで、vpsサーバ契約後の初期設定を一通り行いました。あの作業で、サーバのセキュリティ対策が一通りできたことになります。

今回は「1つのvpsサーバ上に複数のWordpressサイトを立ち上げ、運営する」という目的で作業を行っていきます。

この目的を達成するには、Apacheのバーチャルホストという機能を使います。

バーチャルホストは、ひとつのIPアドレスに対して複数のドメインのマッピングを行う「名前ベース」と複数のIPアドレスを複数のドメインにマッピングする「IPベース」がありますが、ここでは、「名前ベース」の設定を行い、vpsに割りあたっているIPアドレスを、自分で取得した複数のドメイン(サブドメイン)に割り当てることにします。

また、Wordpressを動かすためには、Apacheの他に「PHP」と「MySQL」が必要なので、一緒に設定していきます。

今回は、以下のことを行って行きますよー。

  • Apacheのインストールとセキュリティのための設定
  • PHPのインストール
  • PHPの設定を行う
  • MySQLのインストール
  • WordPressのインストール

 

Apacheのインストールとセキュリティのための設定

それでは最初にWebサーバのApacheをインストールします。

rootで作業しますので、Teraterm等のターミナルソフトで、一般ユーザでログインした後、

$ su

をタイプします。パスワードを聞かれますので、rootのパスワードを入力します。

「su」はswitch userのコマンドで、一時的にrootユーザにスイッチできます。次に

 

#httpd(apache)をyumでインストールする。
$yum -y install httpd

 

と入力します。httpdとその関連モジュールがインストールされます。

cmd1

上記のように、「Complete!」と表示されればインストール完了ですので、次のコマンドを打ちます。これで、VPSサーバを再起動しても、常にApache(httpd)が起動するようになります。

 

$ chkconfig httpd on

 

次にApacheのセキュリティを高める設定を行いましょう。

Apacheの設定は主にhttpd.confというファイルで行っていますので、バックアップを取ったのち、このファイルを書き換えていくことにしましょう。

 

# 設定ファイルのバックアップを取る
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
# 設定ファイルを編集する
vi /etc/httpd/conf/httpd.conf

#以下のように変更
ServerTokens OS
↓
ServerTokens Prod



ServerSignature On
↓
ServerSignature Off


Options Indexes FollowSymLinks
↓
Options -Indexes FollowSymLinks

#Apacheのconfファイルに文法エラーがないか、チェックする
service httpd configtest

Syntax OK と表示されれば問題ありません。 最後に service httpd start と入力し、設定をスタートさせます。
その後、ブラウザを起動し、URLにVPSサーバのIPアドレスを入力しましょう。

下記のようなテストページが表示されればApacheが正常に動いています。

apache2

 

さて、Apacheの稼働が確認できたら、いよいよApacheを複数サイトに対応させる設定を行っていきます。

それには、Apacheのバーチャルホストという機能を使います。

ApacheのバーチャルホストにはNameベースとIPベースの2つの種類がありますが、さくらのVPSではサーバに割り当てられるIPアドレスは基本的に一つですので、同一IPに対するリクエストを複数のWebサイトに振り分けることのできる、Nameベースのバーチャルホスト機能を使うことにしましょう。

 

sample.domain1.netにアクセスされたらsite1に置かれたコンテンツを返し、
test.domain2.netにアクセスされたらsite2に置かれたコンテンツを返す設定例

vhost

 

上記のように、sample.domain1.netにアクセスされたらsite1に置かれたコンテンツを返し、test.domain2.netにアクセスされたらsite2に置かれたコンテンツを返す例で設定を行います。

まず、site1,site2それぞれのコンテンツを配置するためのディレクトリを作成しましょう。

 

# DocumentRootディレクトリを作成する。
mkdir /var/www/html/site1
mkdir /var/www/html/site2
# 作成したディレクトリを一般ユーザでも書き込みできる権限に変更する。
# 下記の「myuser」はご自身の一般ユーザに変更して入力してください。
chown -R myuser.myuser /var/www/html/site1
chown -R myuser.myuser /var/www/html/site2

 

次にNameベースのバーチャルホストの設定を、設定ファイル「/etc/httpd/conf.d/httpd-vhosts.conf」に記述します。

 

# 設定ファイル「httpd-vhosts.conf」をviエディタで開く
vi /etc/httpd/conf.d/httpd-vhosts.conf

上記テキストをターミナルソフトでタイプし、Enterを押して設定ファイルを開いたら「i」を押して編集モードに入ります。

その後、下記のテキストをコピーして、貼り付け、「Esc」で編集モードを抜けた後、「:wq」+Enterで保存します。

設定が保存できたら、下記を入力してApacheを再起動します。

 

/etc/rc.d/init.d/httpd restart

 

FilezillaやWinSCPなどのソフトでDocumentRootディレクトリにホームページのコンテンツをアップロードし、アクセスして表示されることを確認してください。

 

※ドメイン名でアクセスするには、DNSの設定が必要です。
別の記事で解説しますが、さくらVPSに契約したばかりでは、まだ設定できていないと思いますので、
その場合は以下の方法を使います。

Windowsの場合
Windowsでは、ドメイン名とIPアドレスのマッピングをhostsファイルで優先的に行えまます。
つまり、このファイルに記述しておけば、ドメイン名とIPアドレスのマッピングを上書きできるということです。

「C:\Windows\System32\drivers\etc」フォルダにある「hosts」を、管理者権限でエディタで開き、下記の設定を追加します。IPアドレスの「xxx.xxx.xxx.xxx」およびドメイン名は、皆さんの環境に合わせて修正してください。この設定は動的に反映されますので、Windowsの再起動はいりません。

# 下記をhostsファイルに追記
xxx.xxx.xxx.xxx       sample.domain1.net
xxx.xxx.xxx.xxx       test.domain2.net

 

PHPのインストール

それでは次にPHPをインストールします。Root権限のあるユーザでターミナルソフトでログインし、作業しましょう。

私が契約した時のさくらVPSのOSのバージョンであるCentOS6.7の標準リポジトリからインストールできるPHPのバージョンは5.3ですが、上記のようにCentOS6.7の標準リポジトリからインストールできるApache2.2.15を使用している場合、RemiのリポジトリからPHP5.6をインストールすることができます。

 

wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
rpm --upgrade --verbose --hash remi-release-6.rpm
yum install --enablerepo=remi --enablerepo=remi-php56 php php-opcache php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof php-gd

 

途中、必要なパッケージをダウンロードするか聞かれますが、「y」を入力して続行します。
終わったら、「Complete!」もしくは「完了しました!」というメッセージが表示されます。

cmd2

インストールできたら、「php -v」と入力してPHPのバージョンを確認しましょう。

 

PHPの設定を行う

PHPの設定は、「php.ini」ファイルで行います。
変更の前にバックアップをとっておきましょう。

 

# php.iniファイルのバックアップを取る
cp /etc/php.ini /etc/php.ini.org


vi  /etc/php.ini


;error_log = php_erros.log
  ↓ 
error_log = /var/log/php_errors.log


;mbstring.language = Japanese
  ↓
mbstring.language = Japanese



;mbstring.internal_encoding = EUC-JP
  ↓
mbstring.internal_encoding = UTF-8


;mbstring.http_input = auto
 ↓
mbstring.http_input = auto


;mbstring.detect_order = auto
 ↓
mbstring.detect_order = auto



expose_php = on
↓
expose_php = off


;date.timezone = 
 ↓
date.timezone = Asia/Tokyo



service httpd restart

Apahceの再起動が終わったら、phpがうまく設定されているか、確認を行っておきます。info.phpなど適当な名前でファイルを作り、中身を
<? php phpinfo(); ?>

のように記述して、FTPソフトまたはSCPソフトで先ほど設定したサブドメインのルートディレクトリにアップし、アクセスします。

このような画面が表示されればOKです。

php

 

 

MySQLのインストール

次にMySQLをインストールします。

 

yum -y install mysql-server

 

インストールできたら、設定ファイルを修正します。下記の修正は、DBや扱うデフォルトの文字コードをUTF-8に変更するものです。

 

cp /etc/my.cnf /etc/my.cnf.org

vi  /etc/my.cnf

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake


[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqldump]
default-character-set=utf8

修正が終わったら、MySQLのサービスを再起動します。サーバ再起動時にも自動で起動するように、chkconfigもonにしておきましょうか。

 

service mysqld start

chkconfig mysqld on

 

無事起動できたら、rootのパスワードをセットし、それでログインできるかを確認しておきます。

 

mysqladmin -u root password 'xxxxxxxxx'

mysql -u root -p

上記の確認でMySQLにログインし、以下のコマンドを入力すると、DBで設定されているデフォルトの文字コードが表示されますので、変更した設定がきちんときいて、UTF-8になっているかが確認できます。

show variables like 'char%';

dbchar

 

WordPressのインストール

ここまでくれば、あとは、各サイトでWordpressをインストールするだけです。

各RootディレクトリにWordpressのファイルをUploadします。

その後、

CREATE DATABASE xxx_db_name CHARACTER SET utf8;
grant all on xxx_db_name.* to 'xxx_user_name'@'localhost' identified by 'xxxxx_password';

 

で各サイトのWordpress用のDBの作成、ユーザの作成と権限の付与を行い、インストールを行いましょう!

さくらvpsでサブドメインのサイトを立ち上げ、お名前.comでDNS設定を行う

$
0
0

前回の記事で、さくらvpsで、Wrodpressのマルチサイトを設定しました。

各サイトは、実際には「k-forte.net」というドメインに属する、複数のサブドメインとして運営しようと思いますので、Apacheでの設定が終わったら、それらのサブドメインとIPアドレスを紐付けるために、DNSの設定を行う必要があります。

このドメインはお名前.comで取得、管理していますので、DNSの設定もお名前.comで行うことにしましょう。

はじめにお名前.comの管理コンソールにログインし、「ドメインNavi」に行きます。

navi1

 

ドメインNaviに遷移したら、ドメイン設定のタブをクリックします。

navi2

そのタブでは、「ネームサーバーの設定」⇒「DNS関連機能の設定」をクリックしましょう。

navi3

すると、管理対象のドメインの一覧が表示されますので、対象のドメインを選択して、「次へ進む」ボタンを押下します。

navi4ここでは、選択したドメインに対する操作を選べます。DNSレコードの設定を行いたいので、「DNSレコード設定を利用する」の「設定する」ボタンを押します。

navi5さて、この設定画面が一番重要です。

navi6

入力する項目を、ネイキッドドメイン「k-forte.net」、サブドメイン「edu.k-forte.net」で説明すると、以下のように設定し、「追加」ボタンで追加していきます。追加が終わったら、画面下部の「確認画面に進む」で、確認して、確定しましょう。

 

 

最初のテキスト入力欄(ホスト名) TYPE VALUE
A xxx.xxx.xxx.xxx(さくらvpsのIPアドレス)
edu CNAME k-forte.net

 

TTLの項目はデフォルトのままで大丈夫だと思います。

基本的には、ネイキッドドメインはvpsのIPアドレスをレコードタイプ「A」で作成し、サブドメインは、サブドメイン名と紐づくネイキットドメインを、レコードタイプ「CNAME」で作成すればよいと思います。

設定ができたら、しばらく待ちます。最大で2日くらいで反映されます。。

WordPress Popular Postsのサムネイル表示画像が更新されないときの対処方法

$
0
0

多くのサイトで、人気記事を表示させるために、「Wordpress Popular Posts」プラグインを使用していると思います。

このサイトでも使用しており、サムネイル画像表示を行っているのですが、サイト移行を行ったタイミングで、アイキャッチ画像を新たに指定しても、画像の更新がされなくなってしまいました。

 

これは、「Wordpress Popular Posts」がキャッシュという仕組みをもっていて、最初にアイキャッチに指定した画像ファイルを、独自のディレクトリにコピーして、そちらの方を表示に使っているためです。

表示の高速化のために行われる方法ですが、指定した画像が表示されないと困ってしまいますよね。

この、独自ディレクトリにコピーされた画像は、「Wordpress Popular Posts」の設定からクリアすることができます。

 

キャッシュのクリアを行う画面

管理コンソールの「設定」⇒「Wordpress Popular Posts」とたどり、「Wordpress Popular Posts」の設定画面に行きます。

その後、「Tools」タブをクリックします。すると、画面中央あたりに、「Empty image cache」というボタンがありますので、これをクリックしましょう。

pop1

 

confirm

 

下記のように、「Success」と表示されたら、キャッシュが消去されています。

 

ok

 

Permission(権限)のエラーで消去できない というメッセージが表示されたときは、キャッシュのある「Wordpress Popular Posts」の独自ディレクトリに書き込み権限があるかどうかを確認しましょう。

そのディレクトリは、Wordpressをインストールしたディレクトリの下の「wp-content\uploads\wordpress-poplar-posts」ディレクトリで、この下にサムネイルの画像がコピーされています。

このディレクトリの権限を確認してみてくださいね。

Pentaho BIサーバ Community Edition(Ver6)をWindowsでインストールして動かしてみたよ

$
0
0

検索を行ってこのページに来た人はPentahoをBIとして使ってみたい!とか、Pentahoの仲間であるKettleをETLツールとして使ってみたい!と思っている人が多いのではないかと思います。

私自身は、Kettleをお仕事で使う機会があり、非常に使いやすかったので、実践的な使い方を公開することで、ぜひ、いろんな人にも使ってもらいたいと思い、この記事となりました。

 

そもそもPentahoとはオープンソースのBIサーバです。

サブスクリプション版は有償で提供されますが、コミュニティ版は無料で利用することができます

今回は、まず、コミュニティ版のPantahoをBIサーバとして起動してみるところまでやってみます。

 

Pentahoをダウンロードする

このページからコミュニティ版の各製品をダウンロードできます。

画面下部にダウンロードへのリンクがありますので、今回は「Business Analytics Platform」をクリックしましょう。

sorcefogeのPentahoプロジェクトにリンクがはられており、クリックでダウンロードが始まります。

この記事を書いたとき(2016/2/3)は、biserver-ce-6.0.1.0-386.zipがダウンロードされました。

 

Javaをセットアップする

PentahoはJavaで動きますので、Javaをセットアップします。

必要であればjdkのダウンロードを行い、環境変数の「JAVA_HOME」を設定します。

 

ダウンロードしたファイルを解凍

先ほどダウンロードした「biserver-ce-6.0.1.0-386.zip」を適当なディレクトリに解凍します。

「biserver-ce」というディレクトリに展開されます。

 

Pentahoサーバを起動

それでは、サーバの起動を行います。

「biserver-ce」ディレクトリにある、「start-pentaho.bat」をコマンドプロンプトから起動するか、ダブルクリックします。

以前のバージョンでは、Javaの引数に文字コードを指定しないと文字化けしていましたが、バージョン6では特にそのような設定を行わなくても、文字化けは起こりませんでした。

起動が終われば、ブラウザを立ち上げ、Pentahoユーザコンソールを開きます。

URL: http://localhost:8080/pentaho/

p1

ログインには、デフォルトで用意されている管理ユーザ

User name : Admin

Password : password

を使用できます。

 

こんな画面開きましたか??

ログインに成功したら、Pentahoでどのようなことができるか、俯瞰してみることにしましょう。

 

 

Plug-inの利用

Pentahoでは、Plug-inという仕組みで、様々な機能を追加できるようになっており、デフォルトで使用するよりも、主だったplug-inをインストールした方が 格段に使いやすく、いろいろな見た目の分析レポートを作成することができます。

各plug-inはPentaho Marketplaceというところで公開されています。

コンソールから「Marketplace」⇒「Pentaho Marketplace」と遷移すると、各プラグインが閲覧できるサイトが開きますので、見てみましょう。

p2

 

p3

 

下記に、よく使われる、主なpulug-inをご紹介します。

 

CDF(Community Dashboards Framework)

p5-1

CDFは、Pentahoでダッシュボードをデザインしたり、カスタマイズする際に利用するplug-inです。

CSS, HTML5やJavaScriptといった標準的なWeb技術を使ってダイナミックなダッシュボードを作成することを可能にします。

 

CDA(Community Data Access)

p5-2

CDAは、コンソールから、多様なデータソースを透過的に扱うことのできるplug-inです。 異なる種類のデータソース同士を結合したり、データソースからのデータエクスポートをコンソールから可能にします。 CDFに依存していますので、CDFを最初にインストールしておく必要があります。

 

CDE(Community Dashboard Editor)

p5-3

CDEはCDFを利用して、ダッシュボードをもっと細かく設定したり、データソースから動的に生成することをもっときめ細かく行うことができます。 CDFとCDAに依存していますので、CDFとCDAを最初にインストールしておく必要があります。

 

上記以外にも様々なplug-inがありますので、使ってみてください。


PentahoのETLツール「Spoon」でSalesforceのデータをエクセルにエクスポートする

$
0
0

Salesforceのオブジェクトのデータをエクスポートするにはいろいろな方法があります。

    • Dataloaderを使う

よく使われる方法。単一のオブジェクトをCsvへ出力するには便利だが、エクセルなどの形式や、オブジェクト同士の加工、ジョブ化には手間がかかる

    • dataloader.ioを利用する

なかなか良いサービスだと思うが、フリーで使用できるレコード件数に制限があり、それ以上は有料。

    • JitterbitのSalesforce Data Loaderを使う

直感的なインターフェースでマッピングを行え、使いやすい。ジョブスケジュール等のできる上位版のJitterbitHarmonyは有料だが、「Salesforce Data Loader」は無料で利用できる。

ざっとあげてみましたが、それぞれ一長一短で、得意なシーンが異なります。

csvであれば、データローダーだけで十分でしょうが、出力形式がデータベースやエクセルだったりすると、ツールを使った方が便利ですよね。

今回は、CommunityEditionであればフリーで使用できるPentahoのETLツール、「Spoon」を使用してみましょう。

 

Pentaho(Spoon)でできること

Spoonは、PentahoBIツールの中で、ETL部分を担うコンポーネントである「Kettle」の、GUIでETL作業を行うことのできるコンポーネントです。

Spoonを使うと、

  • csvファイルやデータベース、エクセルからデータを抽出して加工し、それをSalesfore登録する。
  • Salesfoeceからデータをcsvやデータベース、エクセルにエクスポートする。
  • csvファイル、エクセルのデータをデータベースにロードする。

といったことを、GUIでのマッピングや設定で簡単に行うことができます。

 

Pentaho(Spoon)のインストールと起動

PentahoのCommunityEditionのページに行って、「Download Section」を押します。

すると、画面下部に移動します。

ここで、「Data Integration」を押すと、ETLツールをダウンロードする「ALL OS」のリンクが表示されます。

「pdi-ce-6.0.1.0-386.zip」をダウンロードして、ローカルのPCの適当なディレクトリに保存しましょう。

保存後、これまた適当なディレクトリで解凍します。

すると、「data-integration」というディレクトリができるはずです。

このディレクトリにある「Spoon.bat」(Windows以外はspoon.sh)をダブルクリックするか、コマンドプロンプトから実行すれば、PentahoのETLツールであるSpoonが起動します。

proxyを通さなければいけない場合は、「Spoon.bat」の下の方の「set OPT」のオプションに、「”-Dhttp.proxyHost=xxxxxx.xxxxx.xx.xx” “-Dhttp.proxyPort=xxxx”」を追加します。

特に、Salesforce等のクラウドと接続を行う場合には、開発環境によってはプロキシの設定が必要になりますので、注意してください。

実行にあたり、エラーが出る場合は、環境変数に「JAVA_HOME」が定義されていないのかもしれませんので、確認してみてください。

 

Salesforceへの接続

Spoonを起動すると、以下のような画面が表示されます。

n1

左側に「データ変換」と「ジョブ」が表示されています。

Spoonでは、一連のデータ加工の方法について定義した「データ変換」(Transform)と、複数の「データ変換」をつなげたり、
「データ変換」に前処理や後処理を付け加えた「ジョブ」をGUIで定義することができます。

今回は「Salesforceのデータをエクセルに出力する」というシンプルな作業であるため、「データ変換」を定義することにします。

 

Salesforce Inputの作成

左側から「データ変換」を選んでダブルクリックしましょう。

n3

左側がデザイン・ビューに切り替わりますので、「入力」→「Salesforce Input」を選んで、中央の領域(ペイン)にドラッグします。

その後、「Salesforce Input」をダブルクリックすると、Salesforceからの入力データの定義を行う画面が開きます。

n4

3つのタブがありますが、はじめに、「接続」タブで定義します。
接続先のSalesforceのサービスURL 
https://www.salesforce.com/services/Soap/u/21.0(本番環境の場合)
https://test.salesforce.com/services/Soap/u/21.0(Sandbox環境の場合)
ユーザ名パスワードを入力します。

上記の設定を行ったら、エクスポート対象のオブジェクトを指定します。

今回は取引先(Account)とします。

クエリの指定もできますので、SOQLを書いて、対象のレコードを絞り込んだり、複雑なデータ構造を抽出することもできます。

次に、「フィールド」タブに行きましょう。

n4-2

「フィールドの取得」ボタンを押すと、Salesforceから定義情報を取得します。

データタープやデータ長も自動でとってきてくれますので、便利ですよ。

Date型の項目に対する「書式」が、「yyyy-MM-dd’T’HH:mm:ss’.000’Z」になっていますが、このバージョン(Ver6)では、うまく扱えないようですので、「yyyy-MM-dd’T’HH:mm:ss’.000’」に変更します。「couldn’t convert string [2016-02-01T09:59:08.000Z] to a date using format [yyyy-MM-dd’T’HH:mm:ss’.000’Z] on offset location 0」というエラーが出てしまう場合は、日付型項目をチェックしてみましょう。

 

エクセルへの出力の作成

では、上記で、Salesforce側の入力を定義しましたので、それをエクセルに出力する定義を行います。

左から、「出力」→「Microsoft Excel Writer」を選んでドラッグします。

n5

その後、「Microsoft Excel Writer」をダブルクリックすると、エクセルへの出力データの定義を行う画面が開きます。

2つのタブがありますが、はじめに、「ファイル&シート」タブで定義します。

n6

今回は出力先のファイル名を定義するだけでいいでしょう。

定義が終わったら、2つをつなぎます。

シフトを押しながら「Salesforce Input」をクリックし、「Microsoft Excel Writer」にドラッグすることで、両者をつなぐことができます。

n7

これで、Salesforceの入力を、エクセルに出力する定義を行えました。

しかし、まだSalesforceから取得したオブジェクトの各フィールドをどのようにエクセルのセルに出力するかを決めないといけません。

最後に、「Microsoft Excel Writer」をダブルクリックして開き、「コンテンツ」タブで、Salesforceから取得するデータをエクセルのセルにどのようにマッピングするかを定義します。

画面下部に「フィールドの取得」ボタンがありますので、押下すると、Salesforce側から流れ込むフィールドが列挙されます。

n7-2

 

これで一通りの定義ができました。

あとは、実行ボタン(下記の画像の「▶」ボタン)を押下すれば、SalesforceのAccountオブジェクトからデータが抽出され、エクセルに書き込まれます。

n8

出力されたエクセルを開いてみると、

n9

こんな感じで出力されていますね!

一度出力の定義をつくれば、あとはボタン一発で好きな時にエクスポートできますので、バッチ化することも可能です。

また、インポートの定義を作れば、エクセルでデータを編集して、その結果をSalesforce側に戻すこともできますよね。

次回はSlesforceへのデータインポート(Upsert)を行ってみたいと思います。

 

エクセルで管理しているマスタをSalesfoerceにUpsertする with Pentaho

$
0
0

前回の記事ではPentaho(Spoon)を使って、Salesforceのデータをエクセルにエクスポートしました。

今回は、エクスポートしたデータを加工して、逆にSalesforceにデータをUpsertしてみようと思います。

エクセルのデータをそのままUpsertできれば、マスタ等をエクセルで管理しておき、変更があったらそのままSalesforceにUpsertするといったこともできますので、非常に便利です。

今回、インプットにつかうエクセルは、前回の記事でエクスポートした「取引先」のものを使いますので、前回記事を参考に、エクセルを用意すると、わかりやすいと思います。

 

更新用項目の準備

今回、取引先(Account)のデータをUpsertするにあたり、更新のキーを新たに定義することにしましょう。オブジェクトIDを更新キー(Upsert Key)にすることもできますが、データベースなど、外部のプライマリ・キーをキーにして更新できた方が、メンテナンス性も高まります。

そのため、あらかじめ、取引先に更新用のキーとして「FK_Key__c」という項目を外部キーとして用意しました。外部キーについては、この記事「Salesforceへのデータ移行に必須の外部ID!オブジェクトIDを使わないでデータ参照する方法①」この記事「Salesforceへのデータ移行に必須の外部ID!オブジェクトIDを使わないでデータ参照する方法② 実践編」に詳しく書きましたので、わからない場合は参考にしてください。

 

n00

Salesforce側の定義を追加したら、エクセル側にも、「取引先FK」という項目を追加しておきます。これが取引先レコードのPKだと考えます。

n0-1

 

では、用意ができましたら、これも前回の記事を参考に、Spoonを起動しましょう!

 

エクセル入力の定義

はじめに入力側の定義を行います。「入力」⇒「Excel入力」を中央にドラッグし、ダブルクリックして定義を開きます。

はじめに「ファイル」タブで定義を行います。タブ名のところに「!ファイル」というびっくりマークがついているのは、まだ定義しないといけない項目が残っているという意味ですね。

はじめに選択するのは、スプレッドシートタイプ(エンジン)です。「Excel 2007 XLSX (Apache POI)」を選択しました。

 

n1

 

次に「ファイルとディレクトリ」で対象の取引先をエクスポートしたエクセルファイルを選択し、「追加」ボタンで追加します。

次に「シート」タブに移ります。ここで、画面下部の「シートの取得」ボタンを押すと、ダイアログが開きますので、対象のシートを選択しましょう。今回は「Sheet1」です。

 

n2

 

最後に、「フィールド」タブで「フィールドの取得」ボタンを押すと、エクセルのシートにある項目が自動で取得されます。確認して、「OK」ボタンを押しましょう。

 

n3

 

 

Salesforce Upseertの定義

次にSalesforce側のUpsertを定義します。左から「Salesforce Upseert」を選択して中央にドラッグし、その後、Shftを押しながら「エクセル入力」から「Salesforce Upseert」にドラッグして線をつなげます。つなぎ終わったら、「Salesforce Upseert」をダブルクリックして定義を開きます。

「ユーザ名」と「パスワード」を適切にいれて、接続できることを確認します。そしてここがポイントですが、「比較フィールド更新」の項目に、Upsertのキーである、「FK_Key__c」を入力します。

n44

 

その後、「フィールド取得」ボタンを押すと、入力であるエクセルの項目が取得されます。わかりやすくするために、項目を削して、「取引先FK」「取引先名」「取引先 電話」「取引先 Fax」だけとします。

 

n5

 

また、「モジュールフィールド」は対応するSalesforce側の項目を選択しなおします。「外部IDを使用」の項目はすべて「N」にします。これは、外部IDを使用して参照(Lookup)を解決するかという指定なので、今回は関係ないです。

 

n6

 

 

実行

それでは、画面上部の実行ボタンを押下して、実行します。

下記のようにSalesforce側にレコードが追加されていることが確認できましたか?

n7

今回、更新キーには「FK_Key__c」を使用しましたので、オブジェクトIDが異なるほかの組織でも同じようにUpsertすることが可能です。

オブジェクトIDに依存してしまうと厄介なSalesforceのレコード管理ですが、外部IDとETLツールをうまく使うと、手間をかけないで管理できそうですよね。

salesoforceおよびapexでの文字数・バイト数のカウントについて

$
0
0

salesoforceおよびapexで、どのように文字数・バイト数がカウントされるかについてまとめておこうと思います。

たとえば、オブジェクトの項目定義で「テキスト型で4文字」と定義されていた場合、半角、全角の混じった文字列はどこまで許容されるでしょうか。

Salesforceの中では文字列はUTF-8で扱われますので、全角は3byte、半角は1byteとなります。
バイト数を確認するコードは、「Blob.valueOf(string).size()」です。

また、全角・半角ともに、1文字は1文字として扱われます。
文字数は「string.length()」で確認できます。

つまり、下記のようなコードで確認すると、、、

String testStr = '1ああ1あ';
System.debug('length=' + testStr.length());
System.debug('byte size=' + Blob.valueOf(testStr).size());

length=5
byte size=11

のように出力されます。
項目定義で「テキスト型で4文字」と定義されていた場合、「1ああ1」までしか入力できないことになりますね。

salesoforceのカスタムオブジェクトを一括で全件削除する方法まとめ

$
0
0

開発環境では、Salesforceのオブジェクトを何度か一括で削除する場面があります。

これは、DBでいう、テーブルのTruncateのようなものです。

取引先,リード,活動,取引先責任者,ケース,ソリューション,商品,レポートであれば、管理コンソールの「データの管理」⇒「一括削除」から対象の標準オブジェクトを選択して一括削除できます。

カスタムオブジェクトの場合はどうすればいいでしょうか。

いくつか方法がありますが、制限事項や手間が変わってきますので、目的に応じて適切な方法を選びましょう。

 

方法①:データローダーで削除する。

以前、この記事「SalesForceのオブジェクトを一括削除する手順」でもご紹介した方法です。

データローダーを使用し、1回、削除対象のデータをcsvにエクスポートし、それを読み込んで、Id指定で対象のデータを削除します。

あまりに大量のデータですとエクスポートが大変ですが、数万件程度のレコード数であれば、エクスポート項目をIdだけ、もしくはIdと名前だけに絞るなど工夫すれば、それほど時間はかかりません。

また、エクスポート時に条件を絞れば、消す対象のレコードを細かく制御できるのも利点ですね。

 

方法②:トランケートする。

管理コンソールで、「カスタマイズ」⇒「ユーザインターフェース」に行き、「設定」⇒「カスタムオブジェクトの切り捨てを有効化」にチェックを入れると、カスタムオブジェクトの定義の画面に「切り捨て」ボタンが表示されるようになるります。

nnn3

 

英語のページでは「Truncating Custom Objects」と表現されており、文字通り「Truncate」という意味のようです。

ただ、

・カスタムインデックスまたは外部 ID があるオブジェクトは削除できない。
・削除後、新しいURLになる。(オブジェクトのプレフィクスが変わる。「https://ap2.salesforce.com/01I」といった、オブジェクト固有の3つの文字列も変わる。)
・オブジェクト定義はゴミ箱に残るが、レコードはゴミ箱に行かない。

などいくつか制限事項があります。

詳しくはこの日本語のSalesforceのページで確認してみてください。

なお、私が試したときは、一度ログアウトしてログインしないと「切り捨て」ボタンは表示されませんでした。

 

方法③:apex batchコードを書いてdeleteする。

簡単なbatch apexのクラスを作り、それを開発者コンソールから実行します。

下記コード中では、変数queryに削除したいクラスを抽出するSOQLを記述します。

また、executeメソッドの引数の「List scope」の「MyTran1__c」は、対象のオブジェクトのAPI名に変更してください。

/**
* 指定したカスタムオブジェクトを削除するバッチクラス
*
*/
public with sharing class MyCustom_DeleteBatch  implements Database.Batchable, Database.Stateful {

    /**
    * コンストラクタ
    * 
    * @param ctx 
    * @return なし
    * @exception なし
    */
    public MyCustom_DeleteBatch(){

    }
    
    /**
    * バッチ開始処理
    * 
    * @param BC
    * @return QueryLocator
    * @exception なし
    */
    public Database.QueryLocator start(Database.BatchableContext BC) {

        System.debug('★★★★start');
           
        // 削除対象データ取得
        String query ='SELECT ' + 
        'Id ' +
        'FROM MyTran1__c ' + 
        ' Where IsDeleted  = FALSE';       

        System.debug('★★query: ' + query);
        return Database.getQueryLocator(query);
    }


    /**
    * バッチ実行処理
    * 
    * @param BC,scope
    * @return なし
    * @exception なし
    */
    public void execute(Database.BatchableContext BC, List scope) {
        
            System.debug('★★★execute');
            
            delete scope;

    }

    
    /**
    * バッチ終了処理
    * 
    * @param BC
    * @return なし
    * @exception なし
    */
    public void finish(Database.BatchableContext BC) {
    
            System.debug('★★★finish');
            
    }
    
    
    


}

クラスの保存ができたら、下記を開発者コンソールから実行すればOKです。

 

MyCustom_DeleteBatch batch = new MyCustom_DeleteBatch();
Database.executeBatch(batch, 200);

ガバナ制限が不安な場合は、executeBatchの引数の「200」を調節してみてください。

いかがでしたでしょうか。

開発で、大量なデータを何度も削除する場合は、「方法③」の「apex batch」を使う方法がいいと思います。

「apex batch」についての詳しい記事は「ガバナ制限を回避した大量データの一括更新にも便利-Batch Apexの使い方」にもかきましたので、参考にしてください。

googleアナリティクスで、ディレクトリ階層ごとにトラフィックを集計・リアルタイム分析する

$
0
0

私は今まで、google analyticsでのアクセス分析はドメイン単位で行ってきました。

ただ、運営するサイトの中には、ディレクトリ形式のWordpressマルチサイトも含まれており、少しずつアクセスが増えていくなかで、サイトごとのアクセス数や人気記事の傾向も把握したいと思うようになってきています。

そこで今回、あるWordpressマルチサイトをサブディレクトリごとに分析できるようにしてみたいと思います。

サイトのディレクトリ構成のイメージは以下のようになっています。

b1

 

ドメイン配下に、複数のディレクトリがあり、その下に各サイトが存在していますね。

もともと、「http://www.xxxxxxxx.xxx」の設定はgoogle analytics上で行っていたとすると、各サイトの分析は、その設定にフィルタの条件を追加していくことで可能になります。

 

まず、analyticsで対象のドメインの「アナリティクス設定」を開きます。

すると、一番右に「ビュー」がありますので、プルダウンから「新しいビューを作成」を選びましょう。

b2

 

すると、ビューの名前とタイムゾーンを指定できる画面に遷移しますので、適当な名前を入力し、東京のタイムゾーンを選択します。

 

b3

 

名前は分かりやすければ何でもOKですので、サイト名等にしました。

これでビューができましたので、「フィルタ」を押して、設定を行います。

現在取得しているトラフィックにフィルタをかけて、あるディレクトリ配下のトラフィックだけを抽出すればいいですね。

 

b4

 

フィルタ名・・・分かりやすい名称であればOK
フィルタの種類の選択・・・右のみを含む
参照元かリンク先の選択・・・サブディレクトリへのトラフィック
式の選択・・・前方が一致
サブディレクトリ・・・「/blogA/」など、各サイトのディレクトリ

を定義して、「保存」ボタンを押したらOKです。

 

適用はリアルタイムで行われます。

b5

 

(以前は反映まで時間がかかったようですね。)
レポートのタブから、きちんと適用されているかを確認してみましょう。

Viewing all 247 articles
Browse latest View live