====== Islandora Microservices ====== * PHP Pear Soap apt-get install php-pear * Fits cd /opt/ git clone https://github.com/harvard-lts/fits * PHP Stomp library apt-get install libcurl4-openssl-dev pkg-config install libssl-dev libsslcommon2-dev apt-get install build-essential pecl install stomp (SSL support disabled) nano -w /etc/php5/apache2/php.ini extension=stomp.so nano -w /etc/php5/cli/php.ini extension=stomp.so * Islandora listener apt-get install git git clone -b taverna-1.x https://github.com/roblib/php_listeners mv php_listeners /opt/ nano -w /opt/php_listeners/config.xml microservice_users.xml 2 https repoURL 443 fedoraAdmin fedoraadminpassword https tavernaserver 123.123.123.124 8443 tavAdmin tavAdminPassword false true 123.123.123.123 61613 /queue/listener.update /opt/fits/fits.sh /var/log/listener.log * Islandora listener patches (for Taverna server 2.5.4) nano -w /opt/php_listeners/connect.php private function processT2flowOnTaverna($stream, $pid, $dsID, $count = 0) { if(empty($dsID)){ $dsID = 'empty_stream_id';//in order to share workflows with ingest and other methods //(like addDatastream) we must always send both a PID and DSID otherwise taverna will complain that //the number of inputs don't match what was defined in the workflow. } try { $prot = empty($this->config_xml->taverna->protocol) ? 'http' : $this->config_xml->taverna->protocol; $context = empty($this->config_xml->taverna->context) ? 'http' : $this->config_xml->taverna->context; $taverna_sender = new TavernaSender($prot, $this->config_xml->taverna->host, $this->config_xml->taverna->port, $context, $this->config_xml->taverna->username, $this->config_xml->taverna->password); //Post t2flow $result = $taverna_sender->send_Message($stream); $uuid = $taverna_sender->parse_UUID($result); if (empty($uuid)) { //This message should never be seen, as it should break in send message first $this->log->lwrite('No UUID was found', "TAVERNA_ERROR"); } else { //uuid has a value $this->log->lwrite('uuid = ' . $uuid, "SERVER_INFO"); $taverna_sender->add_input($uuid, "pid", $pid); $taverna_sender->add_input($uuid, "dsid", $dsID); $result = $taverna_sender->run_t2flow($uuid); $this->log->lwrite('pid = ' . $pid, "SERVER_INFO"); $this->log->lwrite('dsid = ' . $dsID, "SERVER_INFO"); $status = $this->pollStatus($uuid, $taverna_sender); if ($status) { $this->log->lwrite("deleting workflow $uuid $pid $dsID", "SERVER_INFO"); $taverna_sender->delete_t2flow($uuid); } return TRUE; } } catch (Exception $e) { $this->log->lwrite($e->getMessage() . ' ' . $e->getCode(), 'TAVERNA_ERROR', $pid, $dsID, NULL, 'ERROR'); -// $response = $e->getResponse(); -// $responseString = $response['content']; + $responseString = $e->getMessage(); -// $taverna_sender->delete_t2flow($uuid); //try to delete the failed attempt on the taverna server + $response = $taverna_sender->delete_t2flow($uuid); //try to delete the failed attempt on the taverna server //we rest and retry here as the most common taverna error will probable be a 403 forbidden //due to the server being overloaded. sleep(10); if ($count <= 10) { $this->log->lwrite("Taverna error $responseString, workflow t2flow for $pid $dsID failed, sending agian.", 'SERVER_INFO', $pid, $dsID, NULL, 'INFO'); $this->processT2flowOnTaverna($stream, $pid, $dsID, ++$count); } else { $this->log->lwrite($e->getMessage() . ' ' . $e->getCode() . " $pid $dsID reached the maximum number of tries giving up", "SERVER_INFO", $pid, $dsID, NULL, 'ERROR'); $taverna_sender->delete_t2flow($uuid); } return FALSE; //we return false here so a negative ack will be sent. this probably means (depending on the stomp server configs) that //we will get this message again. This prevents us from losing messages but could cause a loop if Taverna is down, //inaccesible or just not responding } } nano -w /opt/php_listeners/tavernaSender.php function run_t2flow($uuid) { $auth = $this->check_credentials($uuid); if (empty($uuid) || !$auth) { throw new TavernaException("Error running t2flow, missing uuid or auth failure"); } $url = $this->hostname . $uuid . '/status/'; $response = $this->curl_connect->tavernaPutRequest($url, 'string', 'Operating', 'text/plain'); -// if ($response['status'] != 200) { + if (($response['status'] != 200) && ($response['status'] != 202)) { throw new TavernaException($response['headers'] . $response['content'], $response['status'], 'run t2flow'); } return $response['headers'] . $response['content']; } * Disable certificate validation in Tuque module to allow SSL between Listener and repository. nano -w /opt/php_listeners/tuque/HttpConnection.php /** * FALSE to stop cURL from verifying the peer's certificate. (Default: TRUE) * @var type boolean */ public $verifyPeer = FALSE; * Enable Apache SSL for Soap server openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/soap.key -out /etc/ssl/certs/soap.crt chmod 400 /etc/ssl/private/soap.key cd /etc/apache2/ cp sites-available/default-ssl sites-available/default-ssl.ORI nano -w sites-available/default-ssl ... SSLEngine on SSLCertificateFile /etc/ssl/certs/soap.crt SSLCertificateKeyFile /etc/ssl/private/soap.key ... a2enmod ssl a2ensite default-ssl a2dissite 000-default nano -w /etc/apache2/ports.conf ##NameVirtualHost *:80 ##Listen 80 service apache2 restart * Islandora PHP Soap Server apt-get install php5-curl service apache2 restart cp -R /opt/php_listeners/soap_server /var/www/ nano -w /var/www/soap_server/config.xml /opt/php_listeners RoblibServices Add to microservice file user, password and public cert to use with soap service. nano -w /opt/php_listeners/microservice_users.xml * Patch php_listener to pass trusted CA to Taverna server nano -w tavernaSender.php function send_credentials($uuid) { if (empty($uuid)) { throw new TavernaException("no uuid specified when sending credentials ", 'send credentials'); } $microservice_users_file = 'microservice_users.xml'; $microservice_users_xml = simplexml_load_file($microservice_users_file); if ($microservice_users_xml == FALSE) { throw new TavernaException("error reading microservice_users.xml using $location/microserice_users.xml", 404, 'send credentials'); } $users = $microservice_users_xml->xpath("//user"); if ($users == FALSE) { throw new TavernaException("Authentication is required, but no users defined in microservice_users_file.xml ", 'send credentials'); } $host = $this->hostname . $uuid . '/security/credentials'; $hostTrust = $this->hostname . $uuid . '/security/trusts'; foreach ($users as $user) { $data = ' ' . $user['serviceUri'] . '        ' . $user['username'] . '        ' . $user['password'] . ' '; $response = $this->curl_connect->postRequest($host, 'String', $data, 'application/xml'); if ($response['status'] != 201) { throw new TavernaException('Error sending credentials ' . $response['headers'] . $response['content'], $response['status'], 'send credentials'); } if ($user['trustCA'] != ""){ $data = '         ' . $user['trustCA'] . ' '; $response = $this->curl_connect->postRequest($hostTrust, 'String', $data, 'application/xml'); if ($response['status'] != 201) { throw new TavernaException('Error sending trusted Identity ' . $response['headers'] . $response['content'], $response['status'], 'send trustedIdentity'); } } } return TRUE; } * Fedora server setup nano -w $FEDORA_HOME/server/config/fedora.fcfg A datastore representing a JMS Destination for APIM events used by the JMS listeners Messaging Destination for API-M events which update the repository A space-separated list of message types that will be delivered to this Destination. Currently, "apimUpdate" and "apimAccess" are the only supported message types. Optional, defaults to topic. Edit XACML and add taverna server IP ADDRESS \\ Edit Fedora server reverse https proxy to allow taverna server IP ADDRESS access (see [[repo371:revp|Reverse proxy (http and https)]] \\ Restart tomcat * Start listener cd /opt/php_listeners php listener.php ps -ef | grep php