@@ -83,6 +83,7 @@ public class BaseObjectStorageSink extends AbstractObjectStorageOperator impleme
8383 public static final String ACTIVE_OBJECTS_METRIC = "nActiveObjects" ;
8484 public static final String CLOSED_OBJECTS_METRIC = "nClosedObjects" ;
8585 public static final String CLOSE_FAILURES_METRIC = "nCloseFailures" ;
86+ public static final String WRITE_FAILURES_METRIC = "nWriteFailures" ;
8687 public static final String EXPIRED_OBJECTS_METRIC = "nExpiredObjects" ;
8788 public static final String EVICTED_OBJECTS_METRIC = "nEvictedObjects" ;
8889 public static final String MAX_CONCURRENT_PARTITIONS_NUM_METRIC = "maxConcurrentPartitionsNum" ;
@@ -185,6 +186,7 @@ public class BaseObjectStorageSink extends AbstractObjectStorageOperator impleme
185186 private Metric nActiveObjects ;
186187 private Metric nClosedObjects ;
187188 private Metric nCloseFailures ;
189+ private Metric nWriteFailures ;
188190 private Metric nExpiredObjects ;
189191 private Metric nEvictedObjects ;
190192 private Metric startupTimeMillisecs ;
@@ -222,6 +224,11 @@ public void setnCloseFailures (Metric nCloseFailures) {
222224 this .nCloseFailures = nCloseFailures ;
223225 }
224226
227+ @ CustomMetric (kind = Metric .Kind .COUNTER , name = "nWriteFailures" , description = "Number of failures during create object or write to object" )
228+ public void setnWriteFailures (Metric nWriteFailures ) {
229+ this .nWriteFailures = nWriteFailures ;
230+ }
231+
225232 @ CustomMetric (kind = Metric .Kind .GAUGE , name = "objectSizeMin" , description = "Minimal size of an object uploaded to COS in bytes." )
226233 public void setobjectSizeMin (Metric objectSizeMin ) {
227234 this .objectSizeMin = objectSizeMin ;
@@ -1227,6 +1234,10 @@ public Metric getCloseObjectsMetric() {
12271234 public Metric getCloseFailuresMetric () {
12281235 return nCloseFailures ;
12291236 }
1237+
1238+ public Metric getWriteFailuresMetric () {
1239+ return nWriteFailures ;
1240+ }
12301241
12311242 public Metric getExpiredObjectsMetric () {
12321243 return nExpiredObjects ;
@@ -1359,22 +1370,35 @@ private void createObject(String partitionPath, String objectname, boolean isWri
13591370 TRACE .log (TraceLevel .INFO , "Create Object '" + objectname + "' with storage format '" + getStorageFormat () + "'" );
13601371 }
13611372
1362- // create new OS object
1363- // if partitioning required - create object in the proper partition
1364- if (isWritable ) {
1365- fObjectToWrite = fOSObjectFactory .createWritableObject (partitionPath , objectname , fHeaderRow , fDataIndex , fDataType , getObjectStorageClient (), this .parquetSchemaStr , this .parquetWriterConfig );
1366- } else {
1367- fObjectToWrite = fOSObjectFactory .createObject (partitionPath , objectname , fHeaderRow , fDataIndex , fDataType );
1368- }
1369-
1370- if ((TRACE .isLoggable (TraceLevel .TRACE )) && (isParquetPartitioned ())) {
1371- TRACE .log (TraceLevel .TRACE , "Register Object '" + objectname + "' in partition registry using partition key '" + fObjectToWrite .getPartitionPath () + "'" );
1373+ try {
1374+ // create new OS object
1375+ // if partitioning required - create object in the proper partition
1376+ if (isWritable ) {
1377+ fObjectToWrite = fOSObjectFactory .createWritableObject (partitionPath , objectname , fHeaderRow , fDataIndex , fDataType , getObjectStorageClient (), this .parquetSchemaStr , this .parquetWriterConfig );
1378+ } else {
1379+ fObjectToWrite = fOSObjectFactory .createObject (partitionPath , objectname , fHeaderRow , fDataIndex , fDataType );
1380+ }
1381+
1382+ if ((TRACE .isLoggable (TraceLevel .TRACE )) && (isParquetPartitioned ())) {
1383+ TRACE .log (TraceLevel .TRACE , "Register Object '" + objectname + "' in partition registry using partition key '" + fObjectToWrite .getPartitionPath () + "'" );
1384+ }
1385+
1386+ // in the OS objects registry
1387+ fOSObjectRegistry .register (fObjectToWrite .getPartitionPath (), fObjectToWrite );
1388+ if ((isConsistentRegion ()) && (isParquetPartitioned )) {
1389+ partitionedPathList .add (fObjectToWrite .getPartitionPath ()); // store object name for here, used by deleteOnReset
1390+ }
13721391 }
1373-
1374- // in the OS objects registry
1375- fOSObjectRegistry .register (fObjectToWrite .getPartitionPath (), fObjectToWrite );
1376- if ((isConsistentRegion ()) && (isParquetPartitioned )) {
1377- partitionedPathList .add (fObjectToWrite .getPartitionPath ()); // store object name for here, used by deleteOnReset
1392+ catch (Exception e ) {
1393+ String errRootCause = com .ibm .streamsx .objectstorage .Utils .getErrorRootCause (e );
1394+ String errMsg = Messages .getString ("OBJECTSTORAGE_SOURCE_NOT_OPENING_OBJECT" , errRootCause );
1395+ TRACE .log (TraceLevel .ERROR , errMsg );
1396+ TRACE .log (TraceLevel .ERROR , "Failed create object: " +objectname +" - Exception: " + e .getMessage ());
1397+ LOGGER .log (TraceLevel .ERROR , errMsg );
1398+ getWriteFailuresMetric ().increment ();
1399+ if (isConsistentRegion ()) {
1400+ throw e ;
1401+ }
13781402 }
13791403 }
13801404
@@ -1458,13 +1482,33 @@ public void processPunctuation(StreamingInput<Tuple> arg0, Punctuation punct)
14581482 fOSObjectRegistry .closeAll ();
14591483 }
14601484 else {
1461- // close synchronously
1462- fOSObjectRegistry .closeAllImmediately ();
1485+ try {
1486+ // close synchronously
1487+ fOSObjectRegistry .closeAllImmediately ();
1488+ }
1489+ catch (Exception e ) {
1490+ String errRootCause = com .ibm .streamsx .objectstorage .Utils .getErrorRootCause (e );
1491+ String errMsg = Messages .getString ("OBJECTSTORAGE_SINK_OBJECT_CLOSE_FAILURE" , getBucketName (), currentObjectName , errRootCause );
1492+ TRACE .log (TraceLevel .ERROR , errMsg );
1493+ TRACE .log (TraceLevel .ERROR , "Failed to close on window punctuation marker. Exception: " + e .getMessage ());
1494+ LOGGER .log (TraceLevel .ERROR , errMsg );
1495+ getActiveObjectsMetric ().setValue (0 );
1496+ getCloseFailuresMetric ().increment ();
1497+ }
14631498 }
14641499 }
14651500 else if (punct == Punctuation .FINAL_MARKER ) {
1466- // close synchronously
1467- fOSObjectRegistry .closeAllImmediately ();
1501+ try {
1502+ // close synchronously
1503+ fOSObjectRegistry .closeAllImmediately ();
1504+ }
1505+ catch (Exception e ) {
1506+ String errRootCause = com .ibm .streamsx .objectstorage .Utils .getErrorRootCause (e );
1507+ String errMsg = Messages .getString ("OBJECTSTORAGE_SINK_OBJECT_CLOSE_FAILURE" , getBucketName (), currentObjectName , errRootCause );
1508+ TRACE .log (TraceLevel .ERROR , errMsg );
1509+ TRACE .log (TraceLevel .ERROR , "Failed to close on final punctuation marker. Exception: " + e .getMessage ());
1510+ LOGGER .log (TraceLevel .ERROR , errMsg );
1511+ }
14681512 super .processPunctuation (arg0 , punct );
14691513 }
14701514 }
@@ -1546,24 +1590,31 @@ synchronized public void process(StreamingInput<Tuple> stream, Tuple tuple)
15461590 createObject (partitionKey , currentObjectName );
15471591
15481592 if (TRACE .isLoggable (TraceLevel .TRACE )) {
1549- TRACE .log (TraceLevel .TRACE , "New object '" + fObjectToWrite .getPath () + "' has been created for partition key '" + partitionKey + "'" );
1593+ if (fObjectToWrite != null ) {
1594+ TRACE .log (TraceLevel .TRACE , "New object '" + fObjectToWrite .getPath () + "' has been created for partition key '" + partitionKey + "'" );
1595+ }
15501596 }
15511597 }
15521598
1553- try {
1554- fObjectToWrite . writeTuple ( tuple , partitionKey , fOSObjectRegistry );
1555- // update metrics
1556- updateCachedDataMetrics ( fObjectToWrite . getTupleDataSize (), true );
1557- } catch ( Exception e ) {
1558- String errRootCause = com . ibm . streamsx . objectstorage . Utils . getErrorRootCause ( e );
1559- String errMsg = Messages . getString ( "OBJECTSTORAGE_SINK_OBJECT_WRITE_FAILURE" , getBucketName (), fObjectToWrite . getPath (), errRootCause );
1560- if ( TRACE . isLoggable ( TraceLevel . ERROR )) {
1599+ if ( fObjectToWrite != null ) {
1600+ try {
1601+ fObjectToWrite . writeTuple ( tuple , partitionKey , fOSObjectRegistry );
1602+ // update metrics
1603+ updateCachedDataMetrics ( fObjectToWrite . getTupleDataSize (), true );
1604+ } catch ( Exception e ) {
1605+ String errRootCause = com . ibm . streamsx . objectstorage . Utils . getErrorRootCause ( e );
1606+ String errMsg = Messages . getString ( "OBJECTSTORAGE_SINK_OBJECT_WRITE_FAILURE" , getBucketName (), fObjectToWrite . getPath (), errRootCause );
15611607 TRACE .log (TraceLevel .ERROR , errMsg );
1562- TRACE .log (TraceLevel .ERROR , "Failed to write to object '"
1563- + fObjectToWrite .getPath () + "' to bucket '" + getBucketName () + "'. Exception: " + e .getMessage ());
1608+ TRACE .log (TraceLevel .ERROR , "Failed to write to object '" + fObjectToWrite .getPath () + "' to bucket '" + getBucketName () + "'. Exception: " + e .getMessage ());
1609+ LOGGER .log (TraceLevel .ERROR , errMsg );
1610+ getWriteFailuresMetric ().increment ();
1611+ if (isConsistentRegion ()) {
1612+ throw new Exception (e );
1613+ }
15641614 }
1565- LOGGER .log (TraceLevel .ERROR , errMsg );
1566- throw new Exception (e );
1615+ }
1616+ else {
1617+ TRACE .log (TraceLevel .ERROR , "No writable object" );
15671618 }
15681619 }
15691620
0 commit comments