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.model;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import org.json.simple.*;
27 import org.json.simple.parser.*;
28 import javax.xml.bind.annotation.XmlRootElement;
31 import org.onap.dmaap.dbcapi.util.DmaapConfig;
33 import io.swagger.annotations.ApiModelProperty;
35 import org.onap.dmaap.dbcapi.service.DmaapService;
36 import org.onap.dmaap.dbcapi.service.TopicService;
40 public class Topic extends DmaapObject {
42 @ApiModelProperty( value="Fully Qualified Topic Name constructed by dbcapi, following the rules for `fqtnStyle`")
44 @ApiModelProperty( value="the short name used by humans, and utilized to construct the `FQTN`")
45 private String topicName;
46 @ApiModelProperty( value="a description of what this Topic is used for")
47 private String topicDescription;
48 private String tnxEnabled;
49 @ApiModelProperty( value="a label used to identify who requested this `Topic` to be provisioned. In the future this "
50 + "may be an AAF Identity.")
52 @ApiModelProperty( value="a reference to an identifier that describes a data format used for this `Topic`")
53 private String formatUuid;
54 @ApiModelProperty( value="An indicator for how this `Topic` should be replicated when there are more than one `MR_Cluster` instances")
55 private ReplicationType replicationCase;
56 @ApiModelProperty( value="the URL of an outside MR instance")
57 private String globalMrURL; // optional: URL of global MR to replicate to/from
58 @ApiModelProperty( value="the construction rule for the `fqtn` field")
59 private FqtnType fqtnStyle;
60 @ApiModelProperty( value="a hook for any versioning needed for managing a `Topic` over time")
61 private String version;
62 @ApiModelProperty( value="the kafka attribute for specifying the number of partitions")
63 private String partitionCount;
64 @ApiModelProperty( value="the kafka attribute for specifying replication within an `MR_Cluster` instance")
65 private String replicationCount;
66 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to publish to this `Topic`")
67 private String publisherRole;
68 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to subscribe to this `Topic`")
69 private String subscriberRole;
71 @ApiModelProperty( value="an array of `MR_Client` objects associated to this `Topic`")
72 private ArrayList<MR_Client> clients;
76 private static Dmaap dmaap = new DmaapService().getDmaap();
78 private static String defaultPartitionCount;
79 private static String defaultReplicationCount;
81 // during unit testing, discovered that presence of dots in some values
82 // creates an unplanned topic namespace as we compose the FQTN.
83 // this may create sensitivity (i.e. 403) for subsequent creation of AAF perms, so best to not allow it
84 private static String removeDots( String source, String def ) {
85 if ( source == null || source.isEmpty()) {
88 return source.replaceAll("\\.", "_");
91 // utility function to generate the FQTN of a topic
92 public String genFqtn( ) {
93 DmaapConfig dc = (DmaapConfig)DmaapConfig.getConfig();
94 String projectId = dc.getProperty("MR.projectID", "99999");
95 CharSequence signal = ".";
97 if ( this.getTopicName().contains( signal )) {
98 // presence of a dot indicates the name is already fully qualified
99 ret = this.getTopicName();
101 // these vars may not contain dots
102 String p = removeDots( projectId, "90909");
103 String v = removeDots( this.getVersion(), "v1");
104 switch( this.getFqtnStyle() ) {
105 case FQTN_PROJECTID_VERSION_FORMAT:
107 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName() + "-" + v;
110 case FQTN_PROJECTID_FORMAT:
112 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName();
115 case FQTN_LEGACY_FORMAT:
116 default: // for backwards compatibility
117 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + this.getTopicName();
131 this.clients = new ArrayList<>();
132 this.lastMod = new Date();
133 this.replicationCase = ReplicationType.Validator("none");
135 logger.debug( "Topic constructor " + this.lastMod );
137 public Topic(String fqtn, String topicName, String topicDescription,
138 String tnxEnabled, String owner) {
141 this.topicName = topicName;
142 this.topicDescription = topicDescription;
143 this.tnxEnabled = tnxEnabled;
147 logger.debug( "Topic constructor w args " + this.getLastMod() );
150 public Topic init() {
151 DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
153 defaultPartitionCount = p.getProperty( "MR.partitionCount", "2");
154 defaultReplicationCount = p.getProperty( "MR.replicationCount", "1");
156 this.setStatus( DmaapObject_Status.NEW );
157 this.replicationCase = ReplicationType.Validator("none");
158 this.fqtnStyle = FqtnType.Validator("none");
159 this.setPartitionCount( defaultPartitionCount );
160 this.setReplicationCount( defaultReplicationCount );
165 // expects a String in JSON format, with known fields to populate Topic object
166 public Topic ( String json ) {
167 JSONParser parser = new JSONParser();
170 jsonObj = (JSONObject) parser.parse( json );
171 } catch ( ParseException pe ) {
172 logger.error( "Error parsing provisioning data: " + json );
173 this.setStatus( DmaapObject_Status.INVALID );
176 this.setFqtn( (String) jsonObj.get( "fqtn" ) );
177 this.setTopicName( (String) jsonObj.get( "topicName" ) );
178 this.setTopicDescription( (String) jsonObj.get( "topicDescription" ));
179 this.setOwner( (String) jsonObj.get( "owner" ) );
180 this.setStatus( (String) jsonObj.get( "status" ) );
181 this.setReplicationCase( ReplicationType.Validator( (String) jsonObj.get( "replicationCase" ) ));
182 this.setFqtnStyle( FqtnType.Validator( (String) jsonObj.get( "fqtnStyle" ) ) );
183 this.setPartitionCount( (String) jsonObj.get("partitionCount"));
186 public String getFqtn() {
189 public void setFqtn(String fqtn) {
192 public String getTopicName() {
195 public void setTopicName(String topicName) {
196 this.topicName = topicName;
198 public String getTopicDescription() {
199 return topicDescription;
201 public void setTopicDescription(String topicDescription) {
202 this.topicDescription = topicDescription;
205 public String getTnxEnabled() {
208 public void setTnxEnabled(String tnxEnabled) {
209 this.tnxEnabled = tnxEnabled;
211 public String getOwner() {
214 public void setOwner(String owner) {
217 public String getPartitionCount() {
218 return partitionCount;
220 public void setPartitionCount(String partitions) {
221 this.partitionCount = partitions;
223 public String getReplicationCount() {
224 return replicationCount;
226 public void setReplicationCount(String replicationCount) {
227 this.replicationCount = replicationCount;
231 public void setClients(ArrayList<MR_Client> clients) {
232 this.clients = clients;
235 public ArrayList<MR_Client> getClients() {
239 @ApiModelProperty( hidden=true )
240 public int getNumClients() {
241 if ( this.clients == null ) {
244 return this.clients.size();
250 public String getFormatUuid() {
256 public void setFormatUuid(String formatUuid) {
257 this.formatUuid = formatUuid;
261 public ReplicationType getReplicationCase() {
262 return replicationCase;
266 public void setReplicationCase(ReplicationType t) {
267 this.replicationCase = t;
269 public FqtnType getFqtnStyle() {
274 public void setFqtnStyle(FqtnType t) {
278 public String getGlobalMrURL() {
284 public void setGlobalMrURL(String globalMrURL) {
285 this.globalMrURL = globalMrURL;
290 public String getVersion() {
296 public void setVersion(String version) {
297 this.version = version;
302 public String getPublisherRole() {
303 return publisherRole;
305 public void setPublisherRole(String publisherRole) {
306 this.publisherRole = publisherRole;
308 public String getSubscriberRole() {
309 return subscriberRole;
311 public void setSubscriberRole(String subscriberRole) {
312 this.subscriberRole = subscriberRole;
314 public String toProvJSON() {
315 StringBuilder str = new StringBuilder();
316 str.append("{ \"topicName\": \"");
317 str.append( this.getFqtn() );
318 str.append( "\", \"topicDescription\": \"");
319 str.append( this.getTopicDescription());
320 str.append( "\", \"partitionCount\": \"");
321 str.append( this.getPartitionCount());
322 str.append( "\", \"replicationCount\": \"");
323 str.append( this.getReplicationCount());
324 str.append( "\" } ");
326 logger.info( str.toString() );
327 return str.toString();
329 @ApiModelProperty( hidden=true )
330 public byte[] getBytes() {
331 return toProvJSON().getBytes(StandardCharsets.UTF_8);