Wednesday, December 19, 2012

.NETからAlfresco API につなぐ(その1)

こんにちは、杉本です。

いつもはこっちで書いてますが、勉強会の報告なのでこちらで書かせてもらいます。こちらでははじめまして。

ぼくは普段 .NET さんとお仕事をしているので、最近 Alfresco をぜんぜん触っていないのですが、今回は Alfresco とちょっと連携するようなコードを書いてみることにしました。

Alfresco は文書管理を行うための巨大な仕組みで、内部には RDB をつかっているわけですが、 API を通すことで Alfresco そのものを文書データベース、として扱うのも良いよね、と思っています。「文書管理の仕組み」を導入するとなるとなんだか大袈裟な気がしますが、別システムでファイルを保存するストアを文書管理 DB にする、というような視点で別システムのサブシステムとして見ることもできるんじゃないでしょうか。

AlfrescoのAPIといえば、普通は WebScript API を使いますね。ところが今回はあえてのSOAPで繋いでみます。


ちなみに、 Alfresco の Wiki をみると、Web Services という項目のところには、

Please note that this API has been superceded by CMIS (specifically, the CMIS SOAP binding). It's use is no longer recommended.

とあって、Web Service はもう使われなくなっていくことが書かれています(そもそも SOAP が……)

ただ、今回はちょっと簡単に実験したかったので、すでに消滅しつつある SOAP でやってみることにしました。続編として他のアクセス方法でもやっていきたいと思います。

環境としては手もとにあるものをそのままつかったので、Visual Studio 2012 で、.NET Framework 4.5 の環境下でやっています。たいしたことはしてないので、おそらく2010、4.0 の組み合わせでもいけると思います。

.NET では通信フレームワークとして WCF というのがあります。今回SOAPでお気軽にやってしまったのにはこれがあって、Web Service だと WDSL が型情報を持っているので戻ってくるオブジェクトのクラスを自動生成してくれるんですよね。 JSON からクラスを推測してくれるライブラリもあるにはありますが、標準で出来る以上たいへんお手軽なので、今回はWeb Serviceをつかって実験したのでした。

さて、WDSLの場所はこれです。

http://<servername:PORT>/alfresco/api/<サービス名>Service?wsdl
サービス名には Repository とか Content とかが入ります。

まずおもむろに Visual Studio 2012 で新規ソリューションとプロジェクトを作成して、「サービス参照の追加」を行います。

サービス参照追加画面がでるので、 URL を指定して、「探索」するとサービスのところにサービス一覧が出るので、それを選択、 OK をおせば完了です。簡単だ!(名前空間は適当に)


つづいて、 WCF で通信する際の設定です。app.config右クリックから[WCF構成の編集]を選べば UI で設定できます(app.configを直接編集しても良いです)昔はこんなのなかったんじゃなかったかなあ。便利だなあ。

[エンドポイント]でサービスを選択、[全般]タブ、項目 Binding が basicHttpBinding (デフォルトのまま)であることを確認します。

[バインド]でサービスを選択[セキュリティ]タブ、[(全般)]の下の項目 mode を TransportWithMessageCredential にセットします。

[MessageSecurityプロパティ]の下の項目 MessageClientCredentialType を UserName にセットします。

AuthenticationService はセキュリティ設定不要、 HTTP で接続します。
それ以外はセキュリティ設定が必要、HTTPSで接続します。

app.configは

    
        
            
                
                
                  
                    
                  
                
              
                
                  
                
              
            
        
        
            
            
            
        
    

こんな感じになりました。

次にコードを書いていきますが、今回はローカルに立てたサーバに繋ぐので SSL とかの処理をバイパスすることにします。


        private bool OnRemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain,  SslPolicyErrors sslPolicyErrors) {
            return true; 
        }

こんなコードを書き、
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);
こんな風に呼べばOKです。

今回はリポジトリサービス、コンテンツサービスを使ってリポジトリやコンテンツにアクセスしてみました。コードを全部載せてしまいます。


using System;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Windows;
using AuthenticationService = WpfApplication1.Alfresco.AuthenticationService;
using ContentService = WpfApplication1.Alfresco.ContentService;
using RepositoryService = WpfApplication1.Alresco.RepositoryService;

namespace WpfApplication1 {
    public partial class App : Application {
        private void Application_Startup(object sender, StartupEventArgs e) {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);

            var authClient = new AuthenticationService.AuthenticationServiceSoapPortClient();
            var ticket = authClient.startSession("takuma.sugimoto", "takuma");


            var repoClient = new RepositoryService.RepositoryServiceSoapPortClient();
            repoClient.ClientCredentials.UserName.UserName = ticket.username;
            repoClient.ClientCredentials.UserName.Password = ticket.ticket;
            var store = repoClient.getStores().FirstOrDefault(p => p.address == "SpacesStore");
            var query = new RepositoryService.Query() {
                statement = "ID:\"workspace://SpacesStore/3763112e-e36f-44de-9992-ab122350bc21\"",
                language = "lucene",
            };
            var result = repoClient.query(new RepositoryService.QueryConfiguration(), store, query, true);
            var resultNode = result.resultSet.rows.FirstOrDefault();
            var path = resultNode.columns.FirstOrDefault(p => p.name == "{http://www.alfresco.org/model/content/1.0}path").value;
            var name = resultNode.columns.FirstOrDefault(p => p.name == "{http://www.alfresco.org/model/content/1.0}name").value;

            var contentClient = new ContentService.ContentServiceSoapPortClient();
            contentClient.ClientCredentials.UserName.UserName = ticket.username;
            contentClient.ClientCredentials.UserName.Password = ticket.ticket;
            var reference = new ContentService.Reference(){
                store =  new ContentService.Store(){scheme = "workspace",address ="SpacesStore"},
                uuid = resultNode.node.id,
            };
            var predicate = new ContentService.Predicate() {Items = new ContentService.Reference[] { reference }};
            var contents = contentClient.read(predicate, "{http://www.alfresco.org/model/content/1.0}content");
            
            var content = contents.FirstOrDefault();
            var url = content.url + "?ticket=" + ticket.ticket;
            
            var req = WebRequest.Create(url);
            using (var rsp = req.GetResponse()) {
                var stm = rsp.GetResponseStream();
                if (stm != null) {
                    using (stm)
                    using (var reader = new StreamReader(stm))
                    using (var writer = File.OpenWrite(@"D:\Users\takuma.sugimoto\Desktop\temp\" + name)) {
                        var count = 0;
                        var buffer = new byte[4096];
                        do {
                            count = stm.Read(buffer, 0, buffer.Length);
                            writer.Write(buffer, 0, count);
                        } while (count != 0);

                    }
                }

            }
        }

        private bool OnRemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain,  SslPolicyErrors sslPolicyErrors) {
            return true; 
        }
    }
}

ID を直接していしてダウンロードしているというサンプルのためのサンプルコードと言った内容ですが、ご容赦ください。ここにポイントがいくつかあります。

  • WCF で自動生成した場合、サービスごとに型が出来てしまうので、おなじリポジトリを指すクラスが別のものになってしまう。
  • ファイル実体のダウンロード用 Web Service はないので、認証済みのトークンをダウンロード URL につけたURLを直にたたいてダウンロードしてくる

こんなところです。最初の問題は自分で型を作ることも出来るのでそれで解決しますが、それをやるのであれば Web Service でやりはじめた意味があまりないので、自分で型クラスを作るのは次回以降、Web Scriptの API と連携するところで試すことにしましょう。

後者も WebScript であれば専用の API があるようです。ただ、このダウンロード URL を直に叩くというやり方も簡単ではあるので、やりかたとして頭に入れておくと良さそうです。

ハイ、そんなわけで、わざわざフェードアウトしつつある技術を使って Alfresco にアクセスしてみました。技術自体は古くてもかなり簡単にアクセスできるように作られていることが分かってもらえたかと思います。今回はここまで。(いつになるかわかりませんが)次回は Web Script の API と CMIS の API で接続することを試してみたいと思います。


Thursday, November 22, 2012

Employees use Dropbox? They will love CmisSync, and IT will benefit

How do you access your company's shared documents?
If your company has an ECM server, chances are you access documents either:
1) Via a web interface
2) As a shared drive

Now there is a third approach: CmisSync synchronizes your company's documents to your personal computer.

Advantage over a web interface:
- They are just normal files on your hard drive. No need to open a browser and download a copy.
- Documents downloaded from a Web interface quickly become outdated. With CmisSync, the files on your hard drive are always up-to-date.

Advantage over a shared drive:
- Slow network does not slow you down.
- Continue using your files even when out of the office, or even in the plane or subway.

The user interface of CmisSync will feel very familiar to Dropbox users.
But instead of having a Dropbox Inc.'s servers stores the files of each user, all of your content is securely stored on your company's ECM server.

(Liferay users can also use Liferay Sync)

Thursday, November 8, 2012

Alfresco勉強会#11 振り返り

こんにちは。てらしたです。

昨日行われた第11回Alfresco勉強会についてのエントリです。
今回も、aegifの二人が資料を元に発表を行いました。

1つ目は吉岡さん(@mryoshio)の「AlfrescoとSolr(中編)」でした。
Alfresco Solr PluginやAlfresco側に用意されているSolr連携用のクラス等について、実際にソースコードを見ながら解説してくれました。ちょっとSolrを使ってみようかなと思っている人はソースコードを確認しながら資料を見ると非常に参考になると思います。タイトルに(中編)とあるとおり、続きがあるということなので興味のある方は次回以降の勉強会に参加していただければと思います。やっぱり後で資料だけ見るより直接説明聞いた方がわかりやすいですしね。気になっていることは質問もできますし。

2つ目は私が「Alfresco 4.2の新機能」について説明しました。
先日、Alfresco Community 4.2bがリリースされたので、4.2で新しくなった機能や特徴について主なものをデモを用いながら紹介しました。ざっと紹介すると、

  • 追加/改良されたダッシュレット
    • 検索用のダッシュレットや画像プレビュー、Site Notice等。
  • Gallery View
    • ドキュメントライブラリの新しい表示形式。
  • Quick Share
    • コンテンツを簡単に公開するための新機能(SNS連携とは別)。
  • ワークフローのUI改善
    • 完了済みタスクや完了済みワークフローを表示できるようになった。

といった内容です。実際にCommunity版を落として試していただければと思います。

次回は12/12(水)を予定しています。12回目が2012年12月12日と12尽くしの回になります。今回の参加者の方から指摘していただいて初めて気付いたんですが。。。
お申込みはこちらからできます。
ご興味ある方はぜひご参加ください。発表者も大歓迎です。

Wednesday, October 31, 2012

AlfrescoとSolr

こんにちは。

今更ながらSolr関連の記事を書きます。
Alfresco 4.0からSolrに対応されました。

本稿では、概要やインストール等の基本事項について書きます。


概要

[Alfresco]
本ブログの読者なら当然ご存じの通り、Alfresco社が開発しているECMソフトウェアです。サブスクリプションを購入するEnterprise版と無償のCommunity版があります。RedHatとFedoraの関係を考えてもらえば分かりやすいかと思います。

Explorer(旧称DM)とShareの2つのUIがあり、現在はShare UIをメインとして開発が進められています。ShareはSpring SurfとYUIを使った今風のインターフェースになっています。

[Solr]
全文検索エンジンのLuceneを検索エンジンとして使う検索プラットフォームです。詳細はこちらをご覧ください。


AlfrescoでSolrを使うメリット・デメリット

[メリット]

  • Alfrescoのクラスタリングを行う場合、検索インデクスのレプリケーションが不要になる。
  • Alfrescoから見て外にあるSolrへHTTPベースの問い合わせを行うだけで検索が済むため、検索部分の冗長化が楽(HTTPサーバの冗長化と同じノリでできそう)


[デメリット]

  • AVMを使用するWCMでは使えない
  • RMモジュールを使えない
  • マルチテナントを使えない
  • トランザクション内でのインデクシング非対応なので、一貫性を重視する場面では使えない (e.g. WebScript内でコンテンツをアップロード後、同一WebScript内で検索を行う場合)


Solrの利用パターン

SolrとAlfrescoをどのように配置するかを考えてみます。

[パターン1: 同居]
AlfrescoとSolrが同じTomcatインスタンス上のWebアプリケーションとして存在するパターンです。Tomcatの起動・停止時に予期せぬエラーが発生したりしそうなのでできるだけやりたくないなというのが個人的な意見です。Alfresco Solr PluginはAlfrescoへ変更情報等を問い合せて定期的に検索インデクスを更新します。

[パターン2: 別居]
AlfrescoとSolrが異なるTomcatインスタンス上に存在するパターンです。こちらも当然Alfresco Solr Pluginが定期的にインデクスの更新作業を行います。

とりあえず別居推奨です。


インストール・設定

少々手抜きですが、過去のものをご覧ください...

[Alfrescoのインストール]
弊社が過去に実施した勉強会資料をご覧ください。

[SolrおよびAlfresco Solr Pluginのインストール]
Alfrescoと同様、過去の勉強会資料をご覧ください。


動作確認

Alfrescoが載っているTomcatのlog4j.propertiesへ次のものを追記します。

log4j.logger.org.alfresco.repo.search.impl.solr.SolrQueryHTTPClient=debug

その後、Alfrescoを起動します。すると次の様なエラーが発生すると思います。

2012-10-24 15:39:48,522  ERROR [ui.common.Utils] [http-8080-4] システムエラーが発生したため、検索できませんでした: 09240004  org.alfresco.repo.search.impl.lucene.LuceneQueryParserException: 09240004 at org.alfresco.repo.search.impl.solr.SolrQueryHTTPClient.executeQuery(SolrQueryHTTPClient.java:364)at org.alfresco.repo.search.impl.solr.SolrQueryLanguage.executeQuery(SolrQueryLanguage.java:49)at org.alfresco.repo.search.impl.solr.SolrSearchService.query(SolrSearchService.java:348)at org.alfresco.repo.search.SearcherComponent.query(SearcherComponent.java:78)(中略)at java.lang.Thread.run(Thread.java:680)Caused by: java.net.ConnectException: Connection refusedat java.net.PlainSocketImpl.socketConnect(Native Method)at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)(後略)

エラーが出れば、AlfrescoがSolrへ接続しようとしていることでOKです。


次にSolrを起動します。その後Alfrescoを再起動し、ログイン後に検索を実行します。
すると次の様なログが出力されます。


2012-10-24 15:45:54,157  DEBUG [impl.solr.SolrQueryHTTPClient] [http-8080-3] Sent :/solr/alfresco/alfresco?q=%28%28+TYPE%3A%22%7Bhttp%3A%2F%2Fwww.alfresco.org%2Fmodel%2Fcontent%2F1.0%7Dcontent%22++AND+%28%40%5C%7Bhttp%5C%3A%2F%2Fwww.alfresco.org%2Fmodel%2Fcontent%2F1.0%5C%7Dname%3A%22simple%22++TEXT%3A%22simple%22%29%29+%28+TYPE%3A%22%7Bhttp%3A%2F%2Fwww.alfresco.org%2Fmodel%2Fcontent%2F1.0%7Dfolder%22++AND+%28%40%5C%7Bhttp%5C%3A%2F%2Fwww.alfresco.org%2Fmodel%2Fcontent%2F1.0%5C%7Dname%3A%22simple%22+%29%29%29+AND+NOT+ASPECT%3A%22sys%3Ahidden%22+&wt=json&fl=*%2Cscore&rows=500&df=TEXT&start=0&locale=ja_JP&fq=%7B%21afts%7DAUTHORITY_FILTER_FROM_JSON&fq=%7B%21afts%7DTENANT_FILTER_FROM_JSON 2012-10-24 15:45:54,157  DEBUG [impl.solr.SolrQueryHTTPClient] [http-8080-3]    with: {"textAttributes":[],"allAttributes":[],"templates":[],"authorities":["GROUP_ALFRESCO_ADMINISTRATORS","GROUP_EMAIL_CONTRIBUTORS","GROUP_EVERYONE","GROUP_site_admins","GROUP_site_admins_SiteManager","GROUP_site_swsdp","GROUP_site_swsdp_SiteManager","ROLE_ADMINISTRATOR","ROLE_AUTHENTICATED","admin"],"tenants":[""],"query":"(( TYPE:\"{http://www.alfresco.org/model/content/1.0}content\"  AND (@\\{http\\://www.alfresco.org/model/content/1.0\\}name:\"simple\"  TEXT:\"simple\")) ( TYPE:\"{http://www.alfresco.org/model/content/1.0}folder\"  AND (@\\{http\\://www.alfresco.org/model/content/1.0\\}name:\"simple\" ))) AND NOT ASPECT:\"sys:hidden\" ","locales":["ja_JP"],"defaultNamespace":"http://www.alfresco.org/model/content/1.0","defaultFTSFieldOperator":"OR","defaultFTSOperator":"OR"} 2012-10-24 15:45:54,157  DEBUG [impl.solr.SolrQueryHTTPClient] [http-8080-3] Got: 6 in 904 ms

おめでとうございます。AlfrescoからSolrへ問い合わせがされたことを確認できました。


今回はここまでになります。この続きは、次回Alfresco勉強会でお話したいと思います。お楽しみに。

@mryoshio

Wednesday, October 24, 2012

Alfrescoのファイルサーバ機能TIPS(CIFSとかFTPとか) その2

こんにちは!大谷です。

今回は、以前の記事「Alfrescoのファイルサーバ機能TIPS(CIFSとかFTPとか) その1」に続き、CIFSやFTP等のファイルサーバ機能についてのお話をしようと思います。前回はファイルサーバ機能の概要と、アクセス方法、アクセス出来ない場合の確認事項について説明しましたが、今回は、ファイルサーバ機能のコンフィギュレーションについていくつかの例を挙げてその方法を説明したいと思います。
なお、本記事は基本的にWindowsを念頭に置いた内容になっているので、LinuxやMax OSをお使いの方は注意してください(まあ基本的なところはOSに依存しないとは思いますが…)。


どこらへんをいじればいいの?


まず、ファイルサーバ機能の設定に関連するファイルを挙げてみます。どのファイルを参考にしてどのファイルをいじればいいのかという目星をつけましょう。
  • <tomcat_dir>/webapps/alfresco/WEB-INF/classes/alfresco/subsystems/fileServers/default/file-servers-context.xml
    • ファイルサーバ機能を提供しているFileServersサブシステムの定義ファイル
    • 一部の設定がパラメータ化されており、*.propertiesファイルで設定できるようになっている。
  • <tomcat_dir>/webapps/alfresco/WEB-INF/classes/alfresco/subsystems/fileServers/default/file-servers.properties
    • 上記定義ファイルのパラメータの値を設定するファイル
  • <tomcat_dir>/webapps/alfresco/WEB-INF/classes/alfresco/repositry.properties
    • ファイルサーバ機能関係の一部のパラメータはこちらのファイルで設定されている
  • <tomcat_dir>/shared/classes/alfresco-global.properties 
    • 上記パラメータを変更する場合に設定を記述するファイル
    • 変更したいパラメータとその値をこのファイルに追記することで、file-servers.propertiesやrepository.propertiesにおける設定内容がこのファイルの設定内容で上書きされ、パラメータ値を変更することができる

というわけで、単純な設定変更であれば、file-servers-context.xmlやfile-servers.propertiesを見て変更すべきパラメータを確認し、alfresco-global.propertiesでそのパラメータの値を設定するだけでOKです。
設定項目の詳細については、Alfresco Helpの「Configuring file servers」alfrescowikiの「File Server Subsystem 4.0」あたりが参考になりますので必要に応じて参照してください(両方とも英語ですすいません…)。

では、実際にいくつかの例を見てみましょう。


例1. CIFSアクセス時のサーバ名を変更したい


前回説明したとおり、CIFSでAlfrescoにアクセスする場合は、サーバ名(正確にはNetBIOS名)としてマシン名+Aという名前を利用します(例えばマシン名がferganaの場合は、\\ferganaAにアクセスする必要があります)。この名前はfile-servers.propertiesで以下のように設定されています。
cifs.serverName=${localname}A
これを変更するために、例えば以下のような設定をalfresco-global.propertiesに追記し、オーバーライドします。
cifs.serverName=TestFileServer
設定が終わったらAlfrescoを再起動し、エクスプローラで\\TestFileServer\Alfresco等にアクセスできることを確認します。なお、デフォルトの設定で使われている${localname}というトークンは、PCのホスト名で置換される特別なトークンです。


例2. Alfrescoフォルダのマップ先を変更したい


デフォルトの設定では、CIFSやFTPでアクセスするとAlfrescoフォルダとAVMフォルダの2フォルダが存在します。さらに、Alfrescoフォルダを開くと、手動インストールだとAlfrescoのCompany_Home以下が、自動インストールだとCompany_Home/Sites以下が表示されます。
このAlfrescoフォルダのマップ先を特定のフォルダに設定するためには、filesystem.rootPathというプロパティをalfresco-global.propertiesでオーバーライドする必要があります。例えば、Alfrescoにログインしてルートフォルダ直下にtestフォルダを作成していくつかファイルをアップロードしておき、alfresco-global.propertiesに以下の行を追加します。
filesystem.rootPath=/app:company_home/cm:test
設定が終わったらAlfrescoを再起動してCIFSやFTPでAlfrescoフォルダにアクセスし、以下のようにAlfrescoフォルダのマップ先が変更されることを確認します。


例3. AVMフォルダを表示したくない、もしくは別のフォルダを追加したい


先ほど話した通り、デフォルトではAlfrescoフォルダとAVMフォルダが存在します。このうちAVMフォルダはWebコンテンツ管理に関連するものなので、表示する必要がないかもしれません。そんな場合は以下の手順でAVMフォルダの設定を抜くことができます。

1. <tomcat_dir>/shared/classes/alfresco/extension以下に、ディレクトリsubsystems/fileServers/default/defaultを作成します。

2. <tomcat_dir>/webapps/alfresco/WEB-INF/classes/alfresco/subsystems/fileServers/default/file-servers-context.xmlを、custom-file-servers-context.xmlという名前で1.で作成したディレクトリにコピーします。

3. custom-file-servers-context.xmlをテキストエディタで開き、filesystemContextsビーン以外の設定を削除し、さらにAVMフォルダの設定も削除します(Alfresco 4.0.dだと以下のようになります)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   <bean id="filesystemContexts" class="org.springframework.beans.factory.config.ListFactoryBean">
      <property name="sourceList">
         <list>
            <!-- Alfresco repository access shared filesystem -->
            <bean class="org.alfresco.filesys.repo.ContentContext">
               <property name="sysAdminParams">
                  <ref bean="sysAdminParams" />
               </property>
               <property name="deviceName">
                  <value>${filesystem.name}</value>
               </property>
               <property name="storeName">
                  <value>${protocols.storeName}</value>
               </property>
               <property name="rootPath">
                  <value>${filesystem.rootPath}</value>
               </property>
               <property name="renameShufflePattern">
                  <value>${filesystem.renameShufflePattern}</value>
               </property>
               
               <!-- Mark locked files as offline -->
               <property name="offlineFiles">
                  <value>true</value>
               </property>
               
               <!-- Enable the quota manager -->
               <property name="quotaManager">
                  <ref bean="filesystemQuotaManager" />
               </property>
               
               <!--  Enables and disables pseudo files - cifs DesktopActions and URL shortcuts. -->
               <property name="pseudoFilesEnabled">
                  <value>${cifs.pseudoFiles.enabled}</value>
               </property>
               
               <!-- Add a pseudo links back to the alfresco explorer -->
               <property name="alfrescoURLEnabled">
                  <value>${cifs.pseudoFiles.explorerURL.enabled}</value>
               </property>
               <property name="URLFileName">
                  <value>${cifs.pseudoFiles.explorerURL.fileName}</value>
               </property>
               
               <!-- Add a pseudo links back to the alfresco share -->
               <property name="shareURLEnabled">
                  <value>${cifs.pseudoFiles.shareURL.enabled}</value>
               </property>
               <property name="shareURLFileName">
                  <value>${cifs.pseudoFiles.shareURL.fileName}</value>
               </property>
               
               <!-- Desktop actions -->
               <!-- Uses a client-side application to trigger a server-side action                         -->
               <!--   Echo - displays a message echoed from the server                                     -->
               <!--   URL  - launches a URL via the Windows shell                                          -->
               <!--   CmdLine - launches the Notepad application                                           -->
               <!--   CheckInOut - checks files in/out, drag and drop files onto the application           -->
               <!--   JavaScript - run a server-side script                                                -->
               <!--   JavaScriptURL - server-side script that generates a URL to the folder using a ticket -->
               <!--                   to avoid having to logon                                             -->
               <property name="globalDesktopActionConfig">
                  <bean class="org.alfresco.filesys.config.GlobalDesktopActionConfigBean">
                     <property name="path">
                        <value>alfresco/desktop/Alfresco.exe</value>
                     </property>
                  </bean>
               </property>
               <property name="desktopActionList">
                  <list>
                     <bean class="org.alfresco.filesys.repo.desk.CheckInOutDesktopAction">
                        <property name="name">
                           <value>CheckInOut</value>
                        </property>
                        <property name="filename">
                           <value>__CheckInOut.exe</value>
                        </property>
                     </bean>
                     <bean class="org.alfresco.filesys.repo.desk.JavaScriptDesktopAction">
                        <property name="name">
                           <value>JavaScriptURL</value>
                        </property>
                        <property name="filename">
                           <value>__ShowDetails.exe</value>
                        </property>
                        <property name="scriptName">
                           <value>alfresco/desktop/showDetails.js</value>
                        </property>
                        <property name="attributeList">
                           <value>anyFiles</value>
                        </property>
                        <property name="preprocess">
                           <value>copyToTarget</value>
                        </property>
                     </bean>
                     <!-- Other desktop actions which may be enabled -->
                     <!--
                        <bean class="org.alfresco.filesys.repo.desk.EchoDesktopAction"> <property name="name">
                        <value>Echo</value> </property> <property name="filename"> <value>__AlfrescoEcho.exe</value>
                        </property> </bean> <bean class="org.alfresco.filesys.repo.desk.URLDesktopAction"> <property
                        name="name"> <value>URL</value> </property> <property name="filename">
                        <value>__AlfrescoURL.exe</value> </property> </bean> <bean
                        class="org.alfresco.filesys.repo.desk.CmdLineDesktopAction"> <property name="name">
                        <value>CmdLine</value> </property> <property name="filename"> <value>__AlfrescoCmd.exe</value>
                        </property> </bean> <bean class="org.alfresco.filesys.repo.desk.JavaScriptDesktopAction">
                        <property name="name"> <value>JavaScript</value> </property> <property name="filename">
                        <value>__AlfrescoScript.exe</value> </property> <property name="scriptName">
                        <value>alfresco/desktop/dumpRequest.js</value> </property> <property name="attributeList">
                        <value>anyFiles, multiplePaths, allowNoParams</value> </property> <property name="preprocess">
                        <value>confirm, copyToTarget</value> </property> </bean>
                     -->
                  </list>
               </property>
               <!-- Additional access control of the filesystem -->
               <!-- Access type of 'none' will stop the filesystem from showing up for that user/address/protocol -->
               <!--
                  <property name="accessControl"> <bean class="org.alfresco.filesys.config.acl.AccessControlListBean">
                  <property name="defaultAccessLevel"> <value>Write</value> </property> </bean> </property>
               -->
            </bean>
         </list>
      </property>
   </bean>
</beans>

4. Alfrescoを再起動し、ftp://<サーバIP>にアクセスします。以下のように、AVMフォルダが表示されなくなっていることを確認します。

上記の手順では、FileServersサブシステムの設定を上書きすることでAVMフォルダを表示しないようにしていますが、同様の手順で、他に必要なフォルダを追加することも可能ですので是非チャレンジしてみてください。
また、サブシステム上書きについては、Alfresco Subsystems - alfrescowikiで詳しく説明されているので、必要に応じて参照してください。


今回は、以上になります。2回に分けて、ファイルサーバ機能の使い方、うまくアクセス出来ない時の対処法、いくつかのコンフィギュレーション例を説明してきました。
この機能はエンドユーザにファイルサーバと同様の使用感のUIを提供するとともに、他システムとの連携の際に相手先のシステムが標準で連携できる(可能性の高い)プロトコルを提供するものですので、実際にAlfrescoの利用を検討している方は、ファイルサーバ機能の利用も検討してみてはいかがでしょうか。

Wednesday, October 17, 2012

Alfresco勉強会#10 振り返り



皆さんこんにちは。

先日行われた第10回Alfresco勉強会についてのエントリです。
今回、aegifの二人が資料を元に発表を行いました。

1つ目はてらしたさん(@terajun)の
ドキュメントライブラリのUIカスタマイズ(一部)」でした。
Alfresco ShareのドキュメントライブラリのUIカスタマイズについて、デモを用いながらわかりやすく説明されていました。Alfresco Shareのカスタマイズは、当初3.x系ではテンプレートファイルを直接編集するなどの方法を採らざるを得なかったのですが、4.xでは設定で行えるようになり、だいぶカスタマイズしやすくなりました。この話は、Alfresco ShareのUIカスタマイズ入門として参考になると思います。

2つ目は私の「Alfresco ShareとGoogle Docs」になります。
機能としてたまに紹介されるGoogle Docs連携ですが、
実際に試した人が少ないのではと考えながら作りました。
ひじょうに簡単な設定で、Alfresco ShareからGoogle Docsへのチェックアウト、
Google DocsからAlfresco Shareへのチェックインができることをデモしました。

次回は11/7(水)を予定しています。
お申込みはこちらからできます。
ご興味ある方はぜひご参加ください。発表者も大歓迎です。
@mryoshio

Wednesday, October 3, 2012

Alfrescoのファイルサーバ機能TIPS(CIFSとかFTPとか) その1

こんにちは。大谷です。

今回はAlfrescoのファイルサーバ機能についてと、それを設定・利用するときに役立つマメ知識とかを書こうと思います。なお、本記事は基本的にWindowsを念頭に置いた内容になっているので、LinuxやMax OSをお使いの方は注意してください(まあ基本的なところはOSに依存しないとは思いますが…)。


ファイルサーバ機能って何?


Alfrescoはコンテンツにアクセスするための様々なインターフェースを用意しています。代表的なものはShareと呼ばれるブラウザアクセス用のGUIですが、その他にも、FTP、SMB/CIFS、WebDAV等でもアクセスできるようなインターフェースを提供しています。
このうちFTPとSMB/CIFS(とNFS。今更感満載なので割愛させてもらいます)の機能は、AlfrescoのFileServersサブシステムと呼ばれるモジュールによって提供されているので、併せてファイルサーバ機能と呼ぶこととします。
いずれもWindowsのエクスプローラや各種ハードウェア・ソフトウェアで簡単にアクセスできるインターフェースなので、ファイルサーバ機能を利用して、エンドユーザが既存のファイル共有サーバライクにAlfrescoを利用したり、スキャナ等から標準のインターフェースを利用して自動的にAlfrescoにファイルをアップロードしたりすることができます。


ファイルサーバ機能を利用するには?


基本的には何の設定もいりません。インストーラを利用しても、手動でインストールしても、FTP、CIFSともデフォルトで有効になっています。逆に、これらの機能を無効にしたい場合は、<tomcat_dir>/shared/classes/alfresco-global.propertiesに以下の設定を追記します。使わない機能を無効にすることは、サーバの負荷を軽減することにつながります。
  • FTP : ftp.enabled=false
  • CIFS : cifs.enabled=false



アクセスしてみよう!


では、実際にアクセスしてみましょう。まずはFTPから。適当なFTPクライアント(WindowsであればエクスプローラでOK)で、ftp://<サーバのIP>にアクセスします。ユーザIDとパスワードの入力を求められるのでAlfrescoに登録されたユーザの情報を入力すると、以下のようにアクセスできるはずです。ルートフォルダにはAlfrescoとAVMの2つのフォルダが存在することが分かります。

次にCIFSを試してみます。Windowsのエクスプローラで、\\<ホスト名>Aにアクセスします。ここで重要なのは、ホスト名の最後に"A"を付けることです(ブロードキャストされるNetBIOS名がデフォルトでこのように設定されているため)。もしアクセスできない場合は、\\<ホスト名>A\Alfrescoにアクセスしてみてください。ユーザIDとパスワードを入力すると以下のようにアクセスできるはずです(swsdpはAlfrescoにデフォルトで設定されているサンプルサイトです)。FTPの例を見ると想像がつくと思いますが、\\<ホスト名>A\AVMにもアクセスすることができます。

ちなみに、FTPやCIFSでAlfrescoフォルダにアクセスした際に表示される内容ですが、手動インストールした場合はAlfrescoリポジトリのルートフォルダ(Company_Homeと呼ばれます)、インストーラでインストールした場合はサイト一覧フォルダ(Company_Home/Sites)が表示されます。後で説明しますが、このルートパスを変更することもできます。


ん、アクセスできないんだけど…


上記のように一発でアクセスできればいいのですが、環境によってはうまくアクセスできないこともあります。ここではありがちな例をいくつか紹介します。

1. CIFSでアクセスできない(認証画面すら表示されない)
この場合は、AlfrescoがインストールされているPCで「コントロール パネル」→「ネットワークとインターネット」→「ネットワーク接続」から、利用しているネットワーク接続のプロパティを開き、「Microsoftネットワーク用ファイルとプリンター共有」のチェックを外してOKボタンをクリックします。
この機能もCIFSを利用しているため、チェックが入っていると競合が発生してAlfrescoにCIFSアクセスできなくなることがあるようです。

2. FTPでアクセスできない(認証画面は通るけどフォルダ一覧の取得に失敗する)
FTPのアクセスモードとファイアウォールの設定に依存している可能性があります。まずはクライアント側の設定でPASVモードを利用しているか否か確認しましょう。エクスプローラでアクセスするのであれば、Internet Explorerの「インターネットオプション」の「詳細設定」タブで「パッシブFTPを使用する」をチェックし、例えばこのチェックを外して再度アクセスできるか確認してみましょう。
もしくは、AlfrescoがインストールされているPCのファイアウォールを確認し、PASVモードが利用する可能性のあるデータポートが開放されているか確認します(ちなみにデフォルト設定のAlfrescoでは利用するポートレンジが指定されていないので、必要に応じてalfresco-global.propertiesにftp.dataPortFrom, ftp.dataPortToプロパティを追加してポートレンジを指定します)。


今回は、AlfrescoへFTPやCIFSのプロトコルを利用したアクセス方法について説明しました。次回は一歩進んで、ファイルサーバ機能の設定をいじってCIFSアクセス時のホスト名を変更したり、アクセス先のルートフォルダを変更したりする方法について説明しようと思います。

(2012/10/24追記:Alfrescoのファイルサーバ機能TIPS(CIFSとかFTPとか) その2 を公開しました)