2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.dmaap.dbcapi.service;
23 import org.onap.dmaap.dbcapi.util.RandomInteger;
25 import java.util.ArrayList;
26 import java.util.List;
29 import javax.ws.rs.core.Response.Status;
31 import org.apache.log4j.Logger;
32 import org.onap.dmaap.dbcapi.aaf.client.DrProvConnection;
33 import org.onap.dmaap.dbcapi.aaf.database.DatabaseClass;
34 import org.onap.dmaap.dbcapi.logging.BaseLoggingClass;
35 import org.onap.dmaap.dbcapi.model.ApiError;
36 import org.onap.dmaap.dbcapi.model.DR_Pub;
37 import org.onap.dmaap.dbcapi.model.DR_Sub;
38 import org.onap.dmaap.dbcapi.model.Feed;
39 import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status;
40 import org.onap.dmaap.dbcapi.util.DmaapConfig;
42 public class FeedService extends BaseLoggingClass {
44 private Map<String, Feed> feeds = DatabaseClass.getFeeds();
45 private DR_PubService pubService = new DR_PubService();
46 private DR_SubService subService = new DR_SubService();
47 private DcaeLocationService dcaeLocations = new DcaeLocationService();
48 private String deleteHandling;
49 private String unit_test;
51 public FeedService() {
52 logger.info( "new FeedService");
53 DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
54 deleteHandling = p.getProperty("Feed.deleteHandling", "DeleteOnDR");
55 unit_test = p.getProperty( "UnitTest", "No" );
59 public Map<String, Feed> getFeeds() {
63 private void getSubObjects( Feed f ) {
64 ArrayList<DR_Pub> pubs = pubService.getDr_PubsByFeedId( f.getFeedId() );
66 ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( f.getFeedId() );
70 public List<Feed> getAllFeeds( String name, String ver, String match ) {
71 logger.info( "getAllFeeds: name=" + name + " ver=" + ver + " match=" + match);
72 ArrayList<Feed> fatFeeds = new ArrayList<Feed>();
73 for( Feed f: feeds.values() ) {
76 if ( match != null && match.equals("startsWith") ) {
77 if ( ! f.getFeedName().startsWith( name ) ) {
78 logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't start with=" + name);
81 } else if ( match != null && match.equals("contains") ) {
82 if ( ! f.getFeedName().contains( name ) ) {
83 logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't contain=" + name);
87 if ( ! f.getFeedName().equals( name ) ) {
88 logger.info( "getAllFeeds: feedName=" + f.getFeedName() + " doesn't equal=" + name);
94 if ( keep && ver != null ) {
95 if ( ! f.getFeedVersion().equals(ver)) {
96 logger.info( "getAllFeeds: feedVersion=" + f.getFeedName() + " doesn't match " + ver);
99 logger.info( "getAllFeeds: feedVersion=" + f.getFeedName() + " matches " + ver);
112 private Feed _getFeed( String key, ApiError err, boolean flag ) {
113 Feed f = feeds.get( key );
114 if ( f != null && ( flag || f.getStatus() != DmaapObject_Status.DELETED ) ) {
117 err.setCode(Status.NOT_FOUND.getStatusCode());
118 err.setMessage("feed not found");
119 err.setFields("feedId=" + key );
125 public Feed getFeed( String key, ApiError err ) {
126 return _getFeed( key, err, false );
128 public Feed getFeedPure( String key, ApiError err ) {
129 return _getFeed( key, err, true );
132 public Feed getFeedByName( String name, String ver, ApiError err ) {
133 for( Feed f: feeds.values() ) {
134 if ( f.getFeedName().equals( name ) && f.getFeedVersion().equals(ver) ) {
140 err.setCode(Status.NOT_FOUND.getStatusCode());
141 err.setMessage("feed not found");
142 err.setFields("feedName=" + name + " and ver=" + ver );
147 private boolean savePubs( Feed f ) {
148 return savePubs( f, f );
150 // need to save the Pub objects independently and copy pubId from original request
151 private boolean savePubs( Feed fnew, Feed req ) {
153 DR_PubService pubSvc = new DR_PubService();
154 ArrayList<DR_Pub> reqPubs = req.getPubs();
155 ArrayList<DR_Pub> newPubs = fnew.getPubs();
159 int nSize = newPubs.size();
160 int rSize = reqPubs.size();
161 logger.info( "reqPubs size=" + rSize + " newPubs size=" + nSize );
162 if ( nSize != rSize ) {
163 errorLogger.error( "Resulting set of publishers do not match requested set of publishers " + nSize + " vs " + rSize );
164 fnew.setStatus( DmaapObject_Status.INVALID);
167 // NOTE: when i > 1 newPubs are in reverse order from reqPubs
168 for( int i = 0; i < reqPubs.size(); i++ ) {
169 DR_Pub reqPub = reqPubs.get(i);
170 ApiError err = new ApiError();
171 if ( pubSvc.getDr_Pub( reqPub.getPubId(), err ) == null ) {
172 DR_Pub newPub = newPubs.get(nSize - i - 1);
173 reqPub.setPubId(newPub.getPubId());
174 reqPub.setFeedId(newPub.getFeedId());
175 reqPub.setStatus(DmaapObject_Status.VALID);
176 if ( reqPub.getDcaeLocationName() == null ) {
177 reqPub.setDcaeLocationName("notSpecified");
179 pubSvc.addDr_Pub( reqPub );
184 fnew.setPubs(reqPubs);
185 fnew.setStatus(DmaapObject_Status.VALID);
190 private boolean saveSubs( Feed f ) {
191 return saveSubs( f, f );
193 // need to save the Sub objects independently
194 private boolean saveSubs( Feed fnew, Feed req ) {
195 ArrayList<DR_Sub> subs = req.getSubs();
196 if ( subs.size() == 0 ) {
197 logger.info( "No subs specified");
199 DR_SubService subSvc = new DR_SubService( fnew.getSubscribeURL() );
200 ApiError err = new ApiError();
201 for( int i = 0; i < subs.size(); i++ ) {
202 DR_Sub sub = subs.get(i);
203 if ( subSvc.getDr_Sub( sub.getSubId(), err) == null ) {
204 subs.set( i, subSvc.addDr_Sub(sub, err));
205 if ( ! err.is2xx()) {
206 logger.error( "i=" + i + " url=" + sub.getDeliveryURL() + " err=" + err.getCode() );
216 fnew.setStatus(DmaapObject_Status.VALID);
221 public Feed addFeed( Feed req, ApiError err ) {
223 // at least 1 pub is required by DR, so create a default pub if none is specified
224 if ( req.getPubs().size() == 0 ) {
225 logger.info( "No pubs specified - creating tmp pub");
226 ArrayList<DR_Pub> pubs = new ArrayList<DR_Pub>();
227 pubs.add( new DR_Pub( dcaeLocations.getCentralLocation())
229 .setRandomPassword());
234 DrProvConnection prov = new DrProvConnection();
235 prov.makeFeedConnection();
236 String resp = prov.doPostFeed( req, err );
237 if ( unit_test.equals( "Yes" ) ) {
238 // assume resp is null, so need to simulate it
239 resp = simulateResp( req, "POST" );
241 logger.info( "resp=" + resp );
242 if ( resp == null ) {
243 switch( err.getCode() ) {
245 err.setFields( "feedName=" + req.getFeedName() + " + feedVersion=" + req.getFeedVersion() );
249 err.setMessage("API deployment/configuration error - contact support");
250 err.setFields( "PROV_AUTH_ADDRESSES");
251 logger.error( "Prov response: 403. " + err.getMessage() + " regarding " + err.getFields() );
255 err.setMessage( "Unexpected response from DR backend" );
256 err.setFields("response");
263 Feed fnew = new Feed( resp );
264 logger.info( "fnew status is:" + fnew.getStatus() );
265 if ( ! fnew.isStatusValid()) {
267 err.setMessage( "Unexpected response from DR backend" );
268 err.setFields("response");
272 //saveChildren( fnew, req );
273 if ( ! savePubs( fnew, req ) || ! saveSubs( fnew, req ) ) {
274 err.setCode(Status.BAD_REQUEST.getStatusCode());
275 err.setMessage("Unable to save Pub or Sub objects");
278 fnew.setFormatUuid(req.getFormatUuid());
280 feeds.put( fnew.getFeedId(), fnew );
284 public Feed updateFeed( Feed req, ApiError err ) {
286 // at least 1 pub is required by DR, so create a default pub if none is specified
287 if ( req.getPubs().size() == 0 ) {
288 logger.info( "No pubs specified - creating tmp pub");
289 ArrayList<DR_Pub> pubs = new ArrayList<DR_Pub>();
290 pubs.add( new DR_Pub( dcaeLocations.getCentralLocation())
292 .setRandomPassword());
296 DrProvConnection prov = new DrProvConnection();
297 prov.makeFeedConnection( req.getFeedId() );
298 String resp = prov.doPutFeed( req, err );
299 if ( unit_test.equals( "Yes" ) ) {
300 // assume resp is null, so need to simulate it
301 resp = simulateResp( req, "PUT" );
303 logger.info( "resp=" + resp );
304 if ( resp == null ) {
305 switch( err.getCode() ) {
307 err.setFields( "feedName=" + req.getFeedName() + " + feedVersion=" + req.getFeedVersion() );
311 err.setMessage("API deployment/configuration error - contact support");
312 err.setFields( "PROV_AUTH_ADDRESSES");
316 err.setMessage( "Unexpected response from DR backend" );
317 err.setFields("response");
323 Feed fnew = new Feed( resp );
324 logger.info( "fnew status is:" + fnew.getStatus() );
325 if ( ! fnew.isStatusValid()) {
327 err.setMessage( "Unexpected response from DR backend" );
328 err.setFields("response");
332 if ( ! savePubs( fnew, req ) || ! saveSubs( fnew, req ) ) {
333 err.setCode(Status.BAD_REQUEST.getStatusCode());
334 err.setMessage("Unable to save Pub or Sub objects");
337 fnew.setFormatUuid(req.getFormatUuid());
339 feeds.put( fnew.getFeedId(), fnew );
345 // DR does not actually delete a feed, so we provide two behaviors:
346 // 1) clean up the feed by removing all subs and pubs, mark it here as DELETED.
347 // then client can add it back if desired.
348 // 2) Call the DR Delete function. Feed with the same name and version can never be added again
350 public Feed removeFeed( Feed req, ApiError err ) {
352 // strip pubs and subs from feed first no matter what
353 ArrayList<DR_Pub> pubs = pubService.getDr_PubsByFeedId( req.getFeedId() );
354 for( DR_Pub pub: pubs ) {
355 pubService.removeDr_Pub(pub.getPubId(), err);
356 if ( ! err.is2xx()) {
360 ArrayList<DR_Sub> subs = subService.getDr_SubsByFeedId( req.getFeedId() );
361 for ( DR_Sub sub: subs ) {
362 subService.removeDr_Sub(sub.getSubId(), err);
363 if ( ! err.is2xx()) {
368 if ( deleteHandling.equalsIgnoreCase("DeleteOnDR")) {
369 DrProvConnection prov = new DrProvConnection();
370 prov.makeFeedConnection( req.getFeedId() );
371 String resp = prov.doDeleteFeed( req, err );
372 if ( unit_test.equals( "Yes" ) ) {
373 // assume resp is null, so need to simulate it
374 resp = simulateDelResp( req );
376 logger.info( "resp=" + resp );
377 if ( resp == null ) {
378 switch( err.getCode() ) {
380 err.setFields( "feedName=" + req.getFeedName() + " + feedVersion=" + req.getFeedVersion() );
384 err.setMessage("API deployment/configuration error - contact support");
385 err.setFields( "PROV_AUTH_ADDRESSES");
389 err.setMessage( "Unexpected response from DR backend" );
390 err.setFields("response");
392 return req; // return back the requested feed - implies it wasn't removed
394 return feeds.remove(req.getFeedId());
396 req.setStatus(DmaapObject_Status.DELETED);
400 feeds.put( req.getFeedId(), req );
407 private String simulateResp( Feed f, String action ){
408 String server = "localhost";
410 if ( action.equals( "POST" ) ) {
411 RandomInteger ran = new RandomInteger(10000);
412 feedid = Integer.toString( ran.next() );
413 } else if ( action.equals( "PUT" ) ) {
414 feedid = f.getFeedId();
418 String ret = String.format(
419 "{\"suspend\":false,\"groupid\":0,\"description\":\"%s\",\"version\":\"1.0\",\"authorization\":{\"endpoint_addrs\":[],\"classification\":\"unclassified\",\"endpoint_ids\":[{\"password\":\"topSecret123\",\"id\":\"sim\"}]},\"name\":\"%s\",\"business_description\":\"\",\"publisher\":\"sim\",\"links\":{\"subscribe\":\"https://%s/subscribe/%s\",\"log\":\"https://%s/feedlog/%s\",\"publish\":\"https://%s/publish/%s\",\"self\":\"https://%s/feed/%s\"}}",
420 f.getFeedDescription(),
430 private String simulateDelResp( Feed f ){
431 String server = "localhost";
432 String feedid = f.getFeedId();
433 String ret = String.format(
434 "{\"suspend\":true,\"groupid\":0,\"description\":\"%s\",\"version\":\"1.0\",\"authorization\":{\"endpoint_addrs\":[],\"classification\":\"unclassified\",\"endpoint_ids\":[{\"password\":\"topSecret123\",\"id\":\"sim\"}]},\"name\":\"%s\",\"business_description\":\"\",\"publisher\":\"sim\",\"links\":{\"subscribe\":\"https://%s/subscribe/%s\",\"log\":\"https://%s/feedlog/%s\",\"publish\":\"https://%s/publish/%s\",\"self\":\"https://%s/feed/%s\"}}",
435 f.getFeedDescription(),